forked from rpms/glibc
		
	import glibc-2.28-66.el8
This commit is contained in:
		
						commit
						0d6119401b
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| SOURCES/glibc-2.28.tar.xz | ||||
							
								
								
									
										1
									
								
								.glibc.metadata
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.glibc.metadata
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1 @@ | ||||
| ccb5dc9e51a9884df8488f86982439d47b283b2a SOURCES/glibc-2.28.tar.xz | ||||
							
								
								
									
										6058
									
								
								SOURCES/ChangeLog.old
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6058
									
								
								SOURCES/ChangeLog.old
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										494
									
								
								SOURCES/SUPPORTED
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										494
									
								
								SOURCES/SUPPORTED
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,494 @@ | ||||
| # This file names the currently supported and somewhat tested locales. | ||||
| # If you have any additions please file a glibc bug report. | ||||
| SUPPORTED-LOCALES=\ | ||||
| C.UTF-8/UTF-8 \ | ||||
| aa_DJ.UTF-8/UTF-8 \ | ||||
| aa_DJ/ISO-8859-1 \ | ||||
| aa_ER/UTF-8 \ | ||||
| aa_ER@saaho/UTF-8 \ | ||||
| aa_ET/UTF-8 \ | ||||
| af_ZA.UTF-8/UTF-8 \ | ||||
| af_ZA/ISO-8859-1 \ | ||||
| agr_PE/UTF-8 \ | ||||
| ak_GH/UTF-8 \ | ||||
| am_ET/UTF-8 \ | ||||
| an_ES.UTF-8/UTF-8 \ | ||||
| an_ES/ISO-8859-15 \ | ||||
| anp_IN/UTF-8 \ | ||||
| ar_AE.UTF-8/UTF-8 \ | ||||
| ar_AE/ISO-8859-6 \ | ||||
| ar_BH.UTF-8/UTF-8 \ | ||||
| ar_BH/ISO-8859-6 \ | ||||
| ar_DZ.UTF-8/UTF-8 \ | ||||
| ar_DZ/ISO-8859-6 \ | ||||
| ar_EG.UTF-8/UTF-8 \ | ||||
| ar_EG/ISO-8859-6 \ | ||||
| ar_IN/UTF-8 \ | ||||
| ar_IQ.UTF-8/UTF-8 \ | ||||
| ar_IQ/ISO-8859-6 \ | ||||
| ar_JO.UTF-8/UTF-8 \ | ||||
| ar_JO/ISO-8859-6 \ | ||||
| ar_KW.UTF-8/UTF-8 \ | ||||
| ar_KW/ISO-8859-6 \ | ||||
| ar_LB.UTF-8/UTF-8 \ | ||||
| ar_LB/ISO-8859-6 \ | ||||
| ar_LY.UTF-8/UTF-8 \ | ||||
| ar_LY/ISO-8859-6 \ | ||||
| ar_MA.UTF-8/UTF-8 \ | ||||
| ar_MA/ISO-8859-6 \ | ||||
| ar_OM.UTF-8/UTF-8 \ | ||||
| ar_OM/ISO-8859-6 \ | ||||
| ar_QA.UTF-8/UTF-8 \ | ||||
| ar_QA/ISO-8859-6 \ | ||||
| ar_SA.UTF-8/UTF-8 \ | ||||
| ar_SA/ISO-8859-6 \ | ||||
| ar_SD.UTF-8/UTF-8 \ | ||||
| ar_SD/ISO-8859-6 \ | ||||
| ar_SS/UTF-8 \ | ||||
| ar_SY.UTF-8/UTF-8 \ | ||||
| ar_SY/ISO-8859-6 \ | ||||
| ar_TN.UTF-8/UTF-8 \ | ||||
| ar_TN/ISO-8859-6 \ | ||||
| ar_YE.UTF-8/UTF-8 \ | ||||
| ar_YE/ISO-8859-6 \ | ||||
| ayc_PE/UTF-8 \ | ||||
| az_AZ/UTF-8 \ | ||||
| az_IR/UTF-8 \ | ||||
| as_IN/UTF-8 \ | ||||
| ast_ES.UTF-8/UTF-8 \ | ||||
| ast_ES/ISO-8859-15 \ | ||||
| be_BY.UTF-8/UTF-8 \ | ||||
| be_BY/CP1251 \ | ||||
| be_BY@latin/UTF-8 \ | ||||
| bem_ZM/UTF-8 \ | ||||
| ber_DZ/UTF-8 \ | ||||
| ber_MA/UTF-8 \ | ||||
| bg_BG.UTF-8/UTF-8 \ | ||||
| bg_BG/CP1251 \ | ||||
| bhb_IN.UTF-8/UTF-8 \ | ||||
| bho_IN/UTF-8 \ | ||||
| bho_NP/UTF-8 \ | ||||
| bi_VU/UTF-8 \ | ||||
| bn_BD/UTF-8 \ | ||||
| bn_IN/UTF-8 \ | ||||
| bo_CN/UTF-8 \ | ||||
| bo_IN/UTF-8 \ | ||||
| br_FR.UTF-8/UTF-8 \ | ||||
| br_FR/ISO-8859-1 \ | ||||
| br_FR@euro/ISO-8859-15 \ | ||||
| brx_IN/UTF-8 \ | ||||
| bs_BA.UTF-8/UTF-8 \ | ||||
| bs_BA/ISO-8859-2 \ | ||||
| byn_ER/UTF-8 \ | ||||
| ca_AD.UTF-8/UTF-8 \ | ||||
| ca_AD/ISO-8859-15 \ | ||||
| ca_ES.UTF-8/UTF-8 \ | ||||
| ca_ES/ISO-8859-1 \ | ||||
| ca_ES@euro/ISO-8859-15 \ | ||||
| ca_ES@valencia/UTF-8 \ | ||||
| ca_FR.UTF-8/UTF-8 \ | ||||
| ca_FR/ISO-8859-15 \ | ||||
| ca_IT.UTF-8/UTF-8 \ | ||||
| ca_IT/ISO-8859-15 \ | ||||
| ce_RU/UTF-8 \ | ||||
| chr_US/UTF-8 \ | ||||
| cmn_TW/UTF-8 \ | ||||
| crh_UA/UTF-8 \ | ||||
| cs_CZ.UTF-8/UTF-8 \ | ||||
| cs_CZ/ISO-8859-2 \ | ||||
| csb_PL/UTF-8 \ | ||||
| cv_RU/UTF-8 \ | ||||
| cy_GB.UTF-8/UTF-8 \ | ||||
| cy_GB/ISO-8859-14 \ | ||||
| da_DK.UTF-8/UTF-8 \ | ||||
| da_DK/ISO-8859-1 \ | ||||
| da_DK.ISO-8859-15/ISO-8859-15 \ | ||||
| de_AT.UTF-8/UTF-8 \ | ||||
| de_AT/ISO-8859-1 \ | ||||
| de_AT@euro/ISO-8859-15 \ | ||||
| de_BE.UTF-8/UTF-8 \ | ||||
| de_BE/ISO-8859-1 \ | ||||
| de_BE@euro/ISO-8859-15 \ | ||||
| de_CH.UTF-8/UTF-8 \ | ||||
| de_CH/ISO-8859-1 \ | ||||
| de_DE.UTF-8/UTF-8 \ | ||||
| de_DE/ISO-8859-1 \ | ||||
| de_DE@euro/ISO-8859-15 \ | ||||
| de_IT.UTF-8/UTF-8 \ | ||||
| de_IT/ISO-8859-1 \ | ||||
| de_LI.UTF-8/UTF-8 \ | ||||
| de_LU.UTF-8/UTF-8 \ | ||||
| de_LU/ISO-8859-1 \ | ||||
| de_LU@euro/ISO-8859-15 \ | ||||
| doi_IN/UTF-8 \ | ||||
| dsb_DE/UTF-8 \ | ||||
| dv_MV/UTF-8 \ | ||||
| dz_BT/UTF-8 \ | ||||
| el_GR.UTF-8/UTF-8 \ | ||||
| el_GR/ISO-8859-7 \ | ||||
| el_GR@euro/ISO-8859-7 \ | ||||
| el_CY.UTF-8/UTF-8 \ | ||||
| el_CY/ISO-8859-7 \ | ||||
| en_AG/UTF-8 \ | ||||
| en_AU.UTF-8/UTF-8 \ | ||||
| en_AU/ISO-8859-1 \ | ||||
| en_BW.UTF-8/UTF-8 \ | ||||
| en_BW/ISO-8859-1 \ | ||||
| en_CA.UTF-8/UTF-8 \ | ||||
| en_CA/ISO-8859-1 \ | ||||
| en_DK.UTF-8/UTF-8 \ | ||||
| en_DK/ISO-8859-1 \ | ||||
| en_GB.UTF-8/UTF-8 \ | ||||
| en_GB/ISO-8859-1 \ | ||||
| en_GB.ISO-8859-15/ISO-8859-15 \ | ||||
| en_HK.UTF-8/UTF-8 \ | ||||
| en_HK/ISO-8859-1 \ | ||||
| en_IE.UTF-8/UTF-8 \ | ||||
| en_IE/ISO-8859-1 \ | ||||
| en_IE@euro/ISO-8859-15 \ | ||||
| en_IL/UTF-8 \ | ||||
| en_IN/UTF-8 \ | ||||
| en_NG/UTF-8 \ | ||||
| en_NZ.UTF-8/UTF-8 \ | ||||
| en_NZ/ISO-8859-1 \ | ||||
| en_PH.UTF-8/UTF-8 \ | ||||
| en_PH/ISO-8859-1 \ | ||||
| en_SC.UTF-8/UTF-8 \ | ||||
| en_SG.UTF-8/UTF-8 \ | ||||
| en_SG/ISO-8859-1 \ | ||||
| en_US.UTF-8/UTF-8 \ | ||||
| en_US/ISO-8859-1 \ | ||||
| en_US.ISO-8859-15/ISO-8859-15 \ | ||||
| en_ZA.UTF-8/UTF-8 \ | ||||
| en_ZA/ISO-8859-1 \ | ||||
| en_ZM/UTF-8 \ | ||||
| en_ZW.UTF-8/UTF-8 \ | ||||
| en_ZW/ISO-8859-1 \ | ||||
| eo/UTF-8 \ | ||||
| es_AR.UTF-8/UTF-8 \ | ||||
| es_AR/ISO-8859-1 \ | ||||
| es_BO.UTF-8/UTF-8 \ | ||||
| es_BO/ISO-8859-1 \ | ||||
| es_CL.UTF-8/UTF-8 \ | ||||
| es_CL/ISO-8859-1 \ | ||||
| es_CO.UTF-8/UTF-8 \ | ||||
| es_CO/ISO-8859-1 \ | ||||
| es_CR.UTF-8/UTF-8 \ | ||||
| es_CR/ISO-8859-1 \ | ||||
| es_CU/UTF-8 \ | ||||
| es_DO.UTF-8/UTF-8 \ | ||||
| es_DO/ISO-8859-1 \ | ||||
| es_EC.UTF-8/UTF-8 \ | ||||
| es_EC/ISO-8859-1 \ | ||||
| es_ES.UTF-8/UTF-8 \ | ||||
| es_ES/ISO-8859-1 \ | ||||
| es_ES@euro/ISO-8859-15 \ | ||||
| es_GT.UTF-8/UTF-8 \ | ||||
| es_GT/ISO-8859-1 \ | ||||
| es_HN.UTF-8/UTF-8 \ | ||||
| es_HN/ISO-8859-1 \ | ||||
| es_MX.UTF-8/UTF-8 \ | ||||
| es_MX/ISO-8859-1 \ | ||||
| es_NI.UTF-8/UTF-8 \ | ||||
| es_NI/ISO-8859-1 \ | ||||
| es_PA.UTF-8/UTF-8 \ | ||||
| es_PA/ISO-8859-1 \ | ||||
| es_PE.UTF-8/UTF-8 \ | ||||
| es_PE/ISO-8859-1 \ | ||||
| es_PR.UTF-8/UTF-8 \ | ||||
| es_PR/ISO-8859-1 \ | ||||
| es_PY.UTF-8/UTF-8 \ | ||||
| es_PY/ISO-8859-1 \ | ||||
| es_SV.UTF-8/UTF-8 \ | ||||
| es_SV/ISO-8859-1 \ | ||||
| es_US.UTF-8/UTF-8 \ | ||||
| es_US/ISO-8859-1 \ | ||||
| es_UY.UTF-8/UTF-8 \ | ||||
| es_UY/ISO-8859-1 \ | ||||
| es_VE.UTF-8/UTF-8 \ | ||||
| es_VE/ISO-8859-1 \ | ||||
| et_EE.UTF-8/UTF-8 \ | ||||
| et_EE/ISO-8859-1 \ | ||||
| et_EE.ISO-8859-15/ISO-8859-15 \ | ||||
| eu_ES.UTF-8/UTF-8 \ | ||||
| eu_ES/ISO-8859-1 \ | ||||
| eu_ES@euro/ISO-8859-15 \ | ||||
| fa_IR/UTF-8 \ | ||||
| ff_SN/UTF-8 \ | ||||
| fi_FI.UTF-8/UTF-8 \ | ||||
| fi_FI/ISO-8859-1 \ | ||||
| fi_FI@euro/ISO-8859-15 \ | ||||
| fil_PH/UTF-8 \ | ||||
| fo_FO.UTF-8/UTF-8 \ | ||||
| fo_FO/ISO-8859-1 \ | ||||
| fr_BE.UTF-8/UTF-8 \ | ||||
| fr_BE/ISO-8859-1 \ | ||||
| fr_BE@euro/ISO-8859-15 \ | ||||
| fr_CA.UTF-8/UTF-8 \ | ||||
| fr_CA/ISO-8859-1 \ | ||||
| fr_CH.UTF-8/UTF-8 \ | ||||
| fr_CH/ISO-8859-1 \ | ||||
| fr_FR.UTF-8/UTF-8 \ | ||||
| fr_FR/ISO-8859-1 \ | ||||
| fr_FR@euro/ISO-8859-15 \ | ||||
| fr_LU.UTF-8/UTF-8 \ | ||||
| fr_LU/ISO-8859-1 \ | ||||
| fr_LU@euro/ISO-8859-15 \ | ||||
| fur_IT/UTF-8 \ | ||||
| fy_NL/UTF-8 \ | ||||
| fy_DE/UTF-8 \ | ||||
| ga_IE.UTF-8/UTF-8 \ | ||||
| ga_IE/ISO-8859-1 \ | ||||
| ga_IE@euro/ISO-8859-15 \ | ||||
| gd_GB.UTF-8/UTF-8 \ | ||||
| gd_GB/ISO-8859-15 \ | ||||
| gez_ER/UTF-8 \ | ||||
| gez_ER@abegede/UTF-8 \ | ||||
| gez_ET/UTF-8 \ | ||||
| gez_ET@abegede/UTF-8 \ | ||||
| gl_ES.UTF-8/UTF-8 \ | ||||
| gl_ES/ISO-8859-1 \ | ||||
| gl_ES@euro/ISO-8859-15 \ | ||||
| gu_IN/UTF-8 \ | ||||
| gv_GB.UTF-8/UTF-8 \ | ||||
| gv_GB/ISO-8859-1 \ | ||||
| ha_NG/UTF-8 \ | ||||
| hak_TW/UTF-8 \ | ||||
| he_IL.UTF-8/UTF-8 \ | ||||
| he_IL/ISO-8859-8 \ | ||||
| hi_IN/UTF-8 \ | ||||
| hif_FJ/UTF-8 \ | ||||
| hne_IN/UTF-8 \ | ||||
| hr_HR.UTF-8/UTF-8 \ | ||||
| hr_HR/ISO-8859-2 \ | ||||
| hsb_DE/ISO-8859-2 \ | ||||
| hsb_DE.UTF-8/UTF-8 \ | ||||
| ht_HT/UTF-8 \ | ||||
| hu_HU.UTF-8/UTF-8 \ | ||||
| hu_HU/ISO-8859-2 \ | ||||
| hy_AM/UTF-8 \ | ||||
| hy_AM.ARMSCII-8/ARMSCII-8 \ | ||||
| ia_FR/UTF-8 \ | ||||
| id_ID.UTF-8/UTF-8 \ | ||||
| id_ID/ISO-8859-1 \ | ||||
| ig_NG/UTF-8 \ | ||||
| ik_CA/UTF-8 \ | ||||
| is_IS.UTF-8/UTF-8 \ | ||||
| is_IS/ISO-8859-1 \ | ||||
| it_CH.UTF-8/UTF-8 \ | ||||
| it_CH/ISO-8859-1 \ | ||||
| it_IT.UTF-8/UTF-8 \ | ||||
| it_IT/ISO-8859-1 \ | ||||
| it_IT@euro/ISO-8859-15 \ | ||||
| iu_CA/UTF-8 \ | ||||
| ja_JP.EUC-JP/EUC-JP \ | ||||
| ja_JP.UTF-8/UTF-8 \ | ||||
| ka_GE.UTF-8/UTF-8 \ | ||||
| ka_GE/GEORGIAN-PS \ | ||||
| kab_DZ/UTF-8 \ | ||||
| kk_KZ.UTF-8/UTF-8 \ | ||||
| kk_KZ/PT154 \ | ||||
| kl_GL.UTF-8/UTF-8 \ | ||||
| kl_GL/ISO-8859-1 \ | ||||
| km_KH/UTF-8 \ | ||||
| kn_IN/UTF-8 \ | ||||
| ko_KR.EUC-KR/EUC-KR \ | ||||
| ko_KR.UTF-8/UTF-8 \ | ||||
| kok_IN/UTF-8 \ | ||||
| ks_IN/UTF-8 \ | ||||
| ks_IN@devanagari/UTF-8 \ | ||||
| ku_TR.UTF-8/UTF-8 \ | ||||
| ku_TR/ISO-8859-9 \ | ||||
| kw_GB.UTF-8/UTF-8 \ | ||||
| kw_GB/ISO-8859-1 \ | ||||
| ky_KG/UTF-8 \ | ||||
| lb_LU/UTF-8 \ | ||||
| lg_UG.UTF-8/UTF-8 \ | ||||
| lg_UG/ISO-8859-10 \ | ||||
| li_BE/UTF-8 \ | ||||
| li_NL/UTF-8 \ | ||||
| lij_IT/UTF-8 \ | ||||
| ln_CD/UTF-8 \ | ||||
| lo_LA/UTF-8 \ | ||||
| lt_LT.UTF-8/UTF-8 \ | ||||
| lt_LT/ISO-8859-13 \ | ||||
| lv_LV.UTF-8/UTF-8 \ | ||||
| lv_LV/ISO-8859-13 \ | ||||
| lzh_TW/UTF-8 \ | ||||
| mag_IN/UTF-8 \ | ||||
| mai_IN/UTF-8 \ | ||||
| mai_NP/UTF-8 \ | ||||
| mfe_MU/UTF-8 \ | ||||
| mg_MG.UTF-8/UTF-8 \ | ||||
| mg_MG/ISO-8859-15 \ | ||||
| mhr_RU/UTF-8 \ | ||||
| mi_NZ.UTF-8/UTF-8 \ | ||||
| mi_NZ/ISO-8859-13 \ | ||||
| miq_NI/UTF-8 \ | ||||
| mjw_IN/UTF-8 \ | ||||
| mk_MK.UTF-8/UTF-8 \ | ||||
| mk_MK/ISO-8859-5 \ | ||||
| ml_IN/UTF-8 \ | ||||
| mn_MN/UTF-8 \ | ||||
| mni_IN/UTF-8 \ | ||||
| mr_IN/UTF-8 \ | ||||
| ms_MY.UTF-8/UTF-8 \ | ||||
| ms_MY/ISO-8859-1 \ | ||||
| mt_MT.UTF-8/UTF-8 \ | ||||
| mt_MT/ISO-8859-3 \ | ||||
| my_MM/UTF-8 \ | ||||
| nan_TW/UTF-8 \ | ||||
| nan_TW@latin/UTF-8 \ | ||||
| nb_NO.UTF-8/UTF-8 \ | ||||
| nb_NO/ISO-8859-1 \ | ||||
| nds_DE/UTF-8 \ | ||||
| nds_NL/UTF-8 \ | ||||
| ne_NP/UTF-8 \ | ||||
| nhn_MX/UTF-8 \ | ||||
| niu_NU/UTF-8 \ | ||||
| niu_NZ/UTF-8 \ | ||||
| nl_AW/UTF-8 \ | ||||
| nl_BE.UTF-8/UTF-8 \ | ||||
| nl_BE/ISO-8859-1 \ | ||||
| nl_BE@euro/ISO-8859-15 \ | ||||
| nl_NL.UTF-8/UTF-8 \ | ||||
| nl_NL/ISO-8859-1 \ | ||||
| nl_NL@euro/ISO-8859-15 \ | ||||
| nn_NO.UTF-8/UTF-8 \ | ||||
| nn_NO/ISO-8859-1 \ | ||||
| nr_ZA/UTF-8 \ | ||||
| nso_ZA/UTF-8 \ | ||||
| oc_FR.UTF-8/UTF-8 \ | ||||
| oc_FR/ISO-8859-1 \ | ||||
| om_ET/UTF-8 \ | ||||
| om_KE.UTF-8/UTF-8 \ | ||||
| om_KE/ISO-8859-1 \ | ||||
| or_IN/UTF-8 \ | ||||
| os_RU/UTF-8 \ | ||||
| pa_IN/UTF-8 \ | ||||
| pa_PK/UTF-8 \ | ||||
| pap_AW/UTF-8 \ | ||||
| pap_CW/UTF-8 \ | ||||
| pl_PL.UTF-8/UTF-8 \ | ||||
| pl_PL/ISO-8859-2 \ | ||||
| ps_AF/UTF-8 \ | ||||
| pt_BR.UTF-8/UTF-8 \ | ||||
| pt_BR/ISO-8859-1 \ | ||||
| pt_PT.UTF-8/UTF-8 \ | ||||
| pt_PT/ISO-8859-1 \ | ||||
| pt_PT@euro/ISO-8859-15 \ | ||||
| quz_PE/UTF-8 \ | ||||
| raj_IN/UTF-8 \ | ||||
| ro_RO.UTF-8/UTF-8 \ | ||||
| ro_RO/ISO-8859-2 \ | ||||
| ru_RU.KOI8-R/KOI8-R \ | ||||
| ru_RU.UTF-8/UTF-8 \ | ||||
| ru_RU/ISO-8859-5 \ | ||||
| ru_UA.UTF-8/UTF-8 \ | ||||
| ru_UA/KOI8-U \ | ||||
| rw_RW/UTF-8 \ | ||||
| sa_IN/UTF-8 \ | ||||
| sah_RU/UTF-8 \ | ||||
| sat_IN/UTF-8 \ | ||||
| sc_IT/UTF-8 \ | ||||
| sd_IN/UTF-8 \ | ||||
| sd_IN@devanagari/UTF-8 \ | ||||
| se_NO/UTF-8 \ | ||||
| sgs_LT/UTF-8 \ | ||||
| shn_MM/UTF-8 \ | ||||
| shs_CA/UTF-8 \ | ||||
| si_LK/UTF-8 \ | ||||
| sid_ET/UTF-8 \ | ||||
| sk_SK.UTF-8/UTF-8 \ | ||||
| sk_SK/ISO-8859-2 \ | ||||
| sl_SI.UTF-8/UTF-8 \ | ||||
| sl_SI/ISO-8859-2 \ | ||||
| sm_WS/UTF-8 \ | ||||
| so_DJ.UTF-8/UTF-8 \ | ||||
| so_DJ/ISO-8859-1 \ | ||||
| so_ET/UTF-8 \ | ||||
| so_KE.UTF-8/UTF-8 \ | ||||
| so_KE/ISO-8859-1 \ | ||||
| so_SO.UTF-8/UTF-8 \ | ||||
| so_SO/ISO-8859-1 \ | ||||
| sq_AL.UTF-8/UTF-8 \ | ||||
| sq_AL/ISO-8859-1 \ | ||||
| sq_MK/UTF-8 \ | ||||
| sr_ME/UTF-8 \ | ||||
| sr_RS/UTF-8 \ | ||||
| sr_RS@latin/UTF-8 \ | ||||
| ss_ZA/UTF-8 \ | ||||
| st_ZA.UTF-8/UTF-8 \ | ||||
| st_ZA/ISO-8859-1 \ | ||||
| sv_FI.UTF-8/UTF-8 \ | ||||
| sv_FI/ISO-8859-1 \ | ||||
| sv_FI@euro/ISO-8859-15 \ | ||||
| sv_SE.UTF-8/UTF-8 \ | ||||
| sv_SE/ISO-8859-1 \ | ||||
| sv_SE.ISO-8859-15/ISO-8859-15 \ | ||||
| sw_KE/UTF-8 \ | ||||
| sw_TZ/UTF-8 \ | ||||
| szl_PL/UTF-8 \ | ||||
| ta_IN/UTF-8 \ | ||||
| ta_LK/UTF-8 \ | ||||
| tcy_IN.UTF-8/UTF-8 \ | ||||
| te_IN/UTF-8 \ | ||||
| tg_TJ.UTF-8/UTF-8 \ | ||||
| tg_TJ/KOI8-T \ | ||||
| th_TH.UTF-8/UTF-8 \ | ||||
| th_TH/TIS-620 \ | ||||
| the_NP/UTF-8 \ | ||||
| ti_ER/UTF-8 \ | ||||
| ti_ET/UTF-8 \ | ||||
| tig_ER/UTF-8 \ | ||||
| tk_TM/UTF-8 \ | ||||
| tl_PH.UTF-8/UTF-8 \ | ||||
| tl_PH/ISO-8859-1 \ | ||||
| tn_ZA/UTF-8 \ | ||||
| to_TO/UTF-8 \ | ||||
| tpi_PG/UTF-8 \ | ||||
| tr_CY.UTF-8/UTF-8 \ | ||||
| tr_CY/ISO-8859-9 \ | ||||
| tr_TR.UTF-8/UTF-8 \ | ||||
| tr_TR/ISO-8859-9 \ | ||||
| ts_ZA/UTF-8 \ | ||||
| tt_RU/UTF-8 \ | ||||
| tt_RU@iqtelif/UTF-8 \ | ||||
| ug_CN/UTF-8 \ | ||||
| uk_UA.UTF-8/UTF-8 \ | ||||
| uk_UA/KOI8-U \ | ||||
| unm_US/UTF-8 \ | ||||
| ur_IN/UTF-8 \ | ||||
| ur_PK/UTF-8 \ | ||||
| uz_UZ.UTF-8/UTF-8 \ | ||||
| uz_UZ/ISO-8859-1 \ | ||||
| uz_UZ@cyrillic/UTF-8 \ | ||||
| ve_ZA/UTF-8 \ | ||||
| vi_VN/UTF-8 \ | ||||
| wa_BE/ISO-8859-1 \ | ||||
| wa_BE@euro/ISO-8859-15 \ | ||||
| wa_BE.UTF-8/UTF-8 \ | ||||
| wae_CH/UTF-8 \ | ||||
| wal_ET/UTF-8 \ | ||||
| wo_SN/UTF-8 \ | ||||
| xh_ZA.UTF-8/UTF-8 \ | ||||
| xh_ZA/ISO-8859-1 \ | ||||
| yi_US.UTF-8/UTF-8 \ | ||||
| yi_US/CP1255 \ | ||||
| yo_NG/UTF-8 \ | ||||
| yue_HK/UTF-8 \ | ||||
| yuw_PG/UTF-8 \ | ||||
| zh_CN.GB18030/GB18030 \ | ||||
| zh_CN.GBK/GBK \ | ||||
| zh_CN.UTF-8/UTF-8 \ | ||||
| zh_CN/GB2312 \ | ||||
| zh_HK.UTF-8/UTF-8 \ | ||||
| zh_HK/BIG5-HKSCS \ | ||||
| zh_SG.UTF-8/UTF-8 \ | ||||
| zh_SG.GBK/GBK \ | ||||
| zh_SG/GB2312 \ | ||||
| zh_TW.EUC-TW/EUC-TW \ | ||||
| zh_TW.UTF-8/UTF-8 \ | ||||
| zh_TW/BIG5 \ | ||||
| zu_ZA.UTF-8/UTF-8 \ | ||||
| zu_ZA/ISO-8859-1 \ | ||||
							
								
								
									
										77
									
								
								SOURCES/bench.mk
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								SOURCES/bench.mk
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,77 @@ | ||||
| objpfx = $(prefix)/$(ver)/usr/libexec/glibc-benchtests/ | ||||
| 
 | ||||
| bench-math := acos acosh asin asinh atan atanh cos cosh exp exp2 ffs ffsll \
 | ||||
| 	      log log2 modf pow rint sin sincos sinh sqrt tan tanh | ||||
| 
 | ||||
| bench-pthread := pthread_once | ||||
| 
 | ||||
| bench := $(bench-math) $(bench-pthread) | ||||
| 
 | ||||
| run-bench := $(prefix)/$(ver)/lib64/ld-linux-x86-64.so.2 --library-path $(prefix)/$(ver)/lib64 $${run} | ||||
| 
 | ||||
| # String function benchmarks.
 | ||||
| string-bench := bcopy bzero memccpy memchr memcmp memcpy memmem memmove \
 | ||||
| 		mempcpy memset rawmemchr stpcpy stpncpy strcasecmp strcasestr \
 | ||||
| 		strcat strchr strchrnul strcmp strcpy strcspn strlen \
 | ||||
| 		strncasecmp strncat strncmp strncpy strnlen strpbrk strrchr \
 | ||||
| 		strspn strstr strcpy_chk stpcpy_chk memrchr strsep strtok | ||||
| string-bench-all := $(string-bench) | ||||
| 
 | ||||
| stdlib-bench := strtod | ||||
| 
 | ||||
| benchset := $(string-bench-all) $(stdlib-bench) | ||||
| 
 | ||||
| bench-malloc := malloc-thread | ||||
| 
 | ||||
| binaries-bench := $(addprefix $(objpfx)bench-,$(bench)) | ||||
| binaries-benchset := $(addprefix $(objpfx)bench-,$(benchset)) | ||||
| binaries-bench-malloc := $(addprefix $(objpfx)bench-,$(bench-malloc)) | ||||
| 
 | ||||
| DETAILED_OPT := | ||||
| 
 | ||||
| ifdef DETAILED | ||||
| 	DETAILED_OPT := -d | ||||
| endif | ||||
| 
 | ||||
| bench: bench-set bench-func bench-malloc | ||||
| 
 | ||||
| bench-set: $(binaries-benchset) | ||||
| 	for run in $^; do \
 | ||||
| 	  outfile=$(prefix)/$$(basename $${run}.$(ver).out); \
 | ||||
| 	  echo "Running $${run}"; \
 | ||||
| 	  $(run-bench) > $${outfile}.tmp; \
 | ||||
| 	  mv $${outfile}{.tmp,}; \
 | ||||
| 	done | ||||
| 
 | ||||
| bench-malloc: $(binaries-bench-malloc) | ||||
| 	run=$(objpfx)bench-malloc-thread; \
 | ||||
| 	outfile=$(prefix)/$$(basename $${run}.$(ver).out); \
 | ||||
| 	for thr in 1 8 16 32; do \
 | ||||
| 	  echo "Running $${run} $${thr}"; \
 | ||||
| 	  $(run-bench) $${thr} > $${outfile}.tmp; \
 | ||||
| 	  mv $${outfile}{.tmp,}; \
 | ||||
| 	done | ||||
| 
 | ||||
| # Build and execute the benchmark functions.  This target generates JSON
 | ||||
| # formatted bench.out.  Each of the programs produce independent JSON output,
 | ||||
| # so one could even execute them individually and process it using any JSON
 | ||||
| # capable language or tool.
 | ||||
| bench-func: $(binaries-bench) | ||||
| 	{ echo "{\"timing_type\": \"hp-timing\","; \
 | ||||
| 	echo " \"functions\": {"; \
 | ||||
| 	for run in $^; do \
 | ||||
| 	  if ! [ "x$${run}" = "x$<" ]; then \
 | ||||
| 	    echo ","; \
 | ||||
| 	  fi; \
 | ||||
| 	  echo "Running $${run}" >&2; \
 | ||||
| 	  $(run-bench) $(DETAILED_OPT); \
 | ||||
| 	done; \
 | ||||
| 	echo; \
 | ||||
| 	echo " }"; \
 | ||||
| 	echo "}"; } > $(prefix)/bench.$(ver).out-tmp; \
 | ||||
| 	if [ -f $(prefix)/bench.$(ver).out ]; then \
 | ||||
| 	  mv -f $(prefix)/bench.$(ver).out{,.old}; \
 | ||||
| 	fi; \
 | ||||
| 	mv -f $(prefix)/bench.$(ver).out{-tmp,} | ||||
| #	scripts/validate_benchout.py bench.out \
 | ||||
| #		scripts/benchout.schema.json
 | ||||
							
								
								
									
										862
									
								
								SOURCES/build-locale-archive.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										862
									
								
								SOURCES/build-locale-archive.c
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,862 @@ | ||||
| #define _GNU_SOURCE | ||||
| #include <assert.h> | ||||
| #include <dirent.h> | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <locale.h> | ||||
| #include <stdarg.h> | ||||
| #include <stdbool.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <getopt.h> | ||||
| #include <string.h> | ||||
| #include <sys/mman.h> | ||||
| #include <sys/stat.h> | ||||
| #include <unistd.h> | ||||
| #include "../locale/hashval.h" | ||||
| #define __LC_LAST 13 | ||||
| #include "../locale/locarchive.h" | ||||
| #include "../crypt/md5.h" | ||||
| 
 | ||||
| const char *alias_file = DATADIR "/locale/locale.alias"; | ||||
| const char *locar_file = PREFIX "/lib/locale/locale-archive"; | ||||
| const char *tmpl_file = PREFIX "/lib/locale/locale-archive.tmpl"; | ||||
| const char *loc_path = PREFIX "/lib/locale/"; | ||||
| /* Flags set by `--verbose` option.  */ | ||||
| int be_quiet = 1; | ||||
| int verbose = 0; | ||||
| int max_locarchive_open_retry = 10; | ||||
| const char *output_prefix; | ||||
| 
 | ||||
| /* Endianness should have been taken care of by localedef.  We don't need to do
 | ||||
|    additional swapping.  We need this variable exported however, since | ||||
|    locarchive.c uses it to determine if it needs to swap endianness of a value | ||||
|    before writing to or reading from the archive.  */ | ||||
| bool swap_endianness_p = false; | ||||
| 
 | ||||
| static const char *locnames[] = | ||||
|   { | ||||
| #define DEFINE_CATEGORY(category, category_name, items, a) \ | ||||
|   [category] = category_name, | ||||
| #include "../locale/categories.def" | ||||
| #undef  DEFINE_CATEGORY | ||||
|   }; | ||||
| 
 | ||||
| static int | ||||
| is_prime (unsigned long candidate) | ||||
| { | ||||
|   /* No even number and none less than 10 will be passed here.  */ | ||||
|   unsigned long int divn = 3; | ||||
|   unsigned long int sq = divn * divn; | ||||
| 
 | ||||
|   while (sq < candidate && candidate % divn != 0) | ||||
|     { | ||||
|       ++divn; | ||||
|       sq += 4 * divn; | ||||
|       ++divn; | ||||
|     } | ||||
| 
 | ||||
|   return candidate % divn != 0; | ||||
| } | ||||
| 
 | ||||
| unsigned long | ||||
| next_prime (unsigned long seed) | ||||
| { | ||||
|   /* Make it definitely odd.  */ | ||||
|   seed |= 1; | ||||
| 
 | ||||
|   while (!is_prime (seed)) | ||||
|     seed += 2; | ||||
| 
 | ||||
|   return seed; | ||||
| } | ||||
| 
 | ||||
| void | ||||
| error (int status, int errnum, const char *message, ...) | ||||
| { | ||||
|   va_list args; | ||||
| 
 | ||||
|   va_start (args, message); | ||||
|   fflush (stdout); | ||||
|   fprintf (stderr, "%s: ", program_invocation_name); | ||||
|   vfprintf (stderr, message, args); | ||||
|   va_end (args); | ||||
|   if (errnum) | ||||
|     fprintf (stderr, ": %s", strerror (errnum)); | ||||
|   putc ('\n', stderr); | ||||
|   fflush (stderr); | ||||
|   if (status) | ||||
|     exit (errnum == EROFS ? 0 : status); | ||||
| } | ||||
| 
 | ||||
| void * | ||||
| xmalloc (size_t size) | ||||
| { | ||||
|   void *p = malloc (size); | ||||
|   if (p == NULL) | ||||
|     error (EXIT_FAILURE, errno, "could not allocate %zd bytes of memory", size); | ||||
|   return p; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| open_tmpl_archive (struct locarhandle *ah) | ||||
| { | ||||
|   struct stat64 st; | ||||
|   int fd; | ||||
|   struct locarhead head; | ||||
|   const char *archivefname = ah->fname == NULL ? tmpl_file : ah->fname; | ||||
| 
 | ||||
|   /* Open the archive.  We must have exclusive write access.  */ | ||||
|   fd = open64 (archivefname, O_RDONLY); | ||||
|   if (fd == -1) | ||||
|     error (EXIT_FAILURE, errno, "cannot open locale archive template file \"%s\"", | ||||
| 	   archivefname); | ||||
| 
 | ||||
|   if (fstat64 (fd, &st) < 0) | ||||
|     error (EXIT_FAILURE, errno, "cannot stat locale archive template file \"%s\"", | ||||
| 	   archivefname); | ||||
| 
 | ||||
|   /* Read the header.  */ | ||||
|   if (TEMP_FAILURE_RETRY (read (fd, &head, sizeof (head))) != sizeof (head)) | ||||
|     error (EXIT_FAILURE, errno, "cannot read archive header"); | ||||
| 
 | ||||
|   ah->fd = fd; | ||||
|   ah->mmaped = (head.sumhash_offset | ||||
| 		+ head.sumhash_size * sizeof (struct sumhashent)); | ||||
|   if (ah->mmaped > (unsigned long) st.st_size) | ||||
|     error (EXIT_FAILURE, 0, "locale archive template file truncated"); | ||||
|   ah->mmaped = st.st_size; | ||||
|   ah->reserved = st.st_size; | ||||
| 
 | ||||
|   /* Now we know how large the administrative information part is.
 | ||||
|      Map all of it.  */ | ||||
|   ah->addr = mmap64 (NULL, ah->mmaped, PROT_READ, MAP_SHARED, fd, 0); | ||||
|   if (ah->addr == MAP_FAILED) | ||||
|     error (EXIT_FAILURE, errno, "cannot map archive header"); | ||||
| } | ||||
| 
 | ||||
| /* Open the locale archive.  */ | ||||
| extern void open_archive (struct locarhandle *ah, bool readonly); | ||||
| 
 | ||||
| /* Close the locale archive.  */ | ||||
| extern void close_archive (struct locarhandle *ah); | ||||
| 
 | ||||
| /* Add given locale data to the archive.  */ | ||||
| extern int add_locale_to_archive (struct locarhandle *ah, const char *name, | ||||
| 				  locale_data_t data, bool replace); | ||||
| 
 | ||||
| extern void add_alias (struct locarhandle *ah, const char *alias, | ||||
| 		       bool replace, const char *oldname, | ||||
| 		       uint32_t *locrec_offset_p); | ||||
| 
 | ||||
| extern struct namehashent * | ||||
| insert_name (struct locarhandle *ah, | ||||
| 	     const char *name, size_t name_len, bool replace); | ||||
| 
 | ||||
| struct nameent | ||||
| { | ||||
|   char *name; | ||||
|   struct locrecent *locrec; | ||||
| }; | ||||
| 
 | ||||
| struct dataent | ||||
| { | ||||
|   const unsigned char *sum; | ||||
|   uint32_t file_offset; | ||||
| }; | ||||
| 
 | ||||
| static int | ||||
| nameentcmp (const void *a, const void *b) | ||||
| { | ||||
|   struct locrecent *la = ((const struct nameent *) a)->locrec; | ||||
|   struct locrecent *lb = ((const struct nameent *) b)->locrec; | ||||
|   uint32_t start_a = -1, end_a = 0; | ||||
|   uint32_t start_b = -1, end_b = 0; | ||||
|   int cnt; | ||||
| 
 | ||||
|   for (cnt = 0; cnt < __LC_LAST; ++cnt) | ||||
|     if (cnt != LC_ALL) | ||||
|       { | ||||
| 	if (la->record[cnt].offset < start_a) | ||||
| 	  start_a = la->record[cnt].offset; | ||||
| 	if (la->record[cnt].offset + la->record[cnt].len > end_a) | ||||
| 	  end_a = la->record[cnt].offset + la->record[cnt].len; | ||||
|       } | ||||
|   assert (start_a != (uint32_t)-1); | ||||
|   assert (end_a != 0); | ||||
| 
 | ||||
|   for (cnt = 0; cnt < __LC_LAST; ++cnt) | ||||
|     if (cnt != LC_ALL) | ||||
|       { | ||||
| 	if (lb->record[cnt].offset < start_b) | ||||
| 	  start_b = lb->record[cnt].offset; | ||||
| 	if (lb->record[cnt].offset + lb->record[cnt].len > end_b) | ||||
| 	  end_b = lb->record[cnt].offset + lb->record[cnt].len; | ||||
|       } | ||||
|   assert (start_b != (uint32_t)-1); | ||||
|   assert (end_b != 0); | ||||
| 
 | ||||
|   if (start_a != start_b) | ||||
|     return (int)start_a - (int)start_b; | ||||
|   return (int)end_a - (int)end_b; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| dataentcmp (const void *a, const void *b) | ||||
| { | ||||
|   if (((const struct dataent *) a)->file_offset | ||||
|       < ((const struct dataent *) b)->file_offset) | ||||
|     return -1; | ||||
| 
 | ||||
|   if (((const struct dataent *) a)->file_offset | ||||
|       > ((const struct dataent *) b)->file_offset) | ||||
|     return 1; | ||||
| 
 | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| sumsearchfn (const void *key, const void *ent) | ||||
| { | ||||
|   uint32_t keyn = *(uint32_t *)key; | ||||
|   uint32_t entn = ((struct dataent *)ent)->file_offset; | ||||
| 
 | ||||
|   if (keyn < entn) | ||||
|     return -1; | ||||
|   if (keyn > entn) | ||||
|     return 1; | ||||
|   return 0; | ||||
| } | ||||
| 
 | ||||
| static void | ||||
| compute_data (struct locarhandle *ah, struct nameent *name, size_t sumused, | ||||
| 	      struct dataent *files, locale_data_t data) | ||||
| { | ||||
|   int cnt; | ||||
|   struct locrecent *locrec = name->locrec; | ||||
|   struct dataent *file; | ||||
|   data[LC_ALL].addr = ((char *) ah->addr) + locrec->record[LC_ALL].offset; | ||||
|   data[LC_ALL].size = locrec->record[LC_ALL].len; | ||||
|   for (cnt = 0; cnt < __LC_LAST; ++cnt) | ||||
|     if (cnt != LC_ALL) | ||||
|       { | ||||
| 	data[cnt].addr = ((char *) ah->addr) + locrec->record[cnt].offset; | ||||
| 	data[cnt].size = locrec->record[cnt].len; | ||||
| 	if (data[cnt].addr >= data[LC_ALL].addr | ||||
| 	    && data[cnt].addr + data[cnt].size | ||||
| 	       <= data[LC_ALL].addr + data[LC_ALL].size) | ||||
| 	  __md5_buffer (data[cnt].addr, data[cnt].size, data[cnt].sum); | ||||
| 	else | ||||
| 	  { | ||||
| 	    file = bsearch (&locrec->record[cnt].offset, files, sumused, | ||||
| 			    sizeof (*files), sumsearchfn); | ||||
| 	    if (file == NULL) | ||||
| 	      error (EXIT_FAILURE, 0, "inconsistent template file"); | ||||
| 	    memcpy (data[cnt].sum, file->sum, sizeof (data[cnt].sum)); | ||||
| 	  } | ||||
|       } | ||||
| } | ||||
| 
 | ||||
| static int | ||||
| fill_archive (struct locarhandle *tmpl_ah, | ||||
| 	      const char *fname, | ||||
| 	      size_t install_langs_count, char *install_langs_list[], | ||||
| 	      size_t nlist, char *list[], | ||||
| 	      const char *primary) | ||||
| { | ||||
|   struct locarhandle ah; | ||||
|   struct locarhead *head; | ||||
|   int result = 0; | ||||
|   struct nameent *names; | ||||
|   struct namehashent *namehashtab; | ||||
|   size_t cnt, used; | ||||
|   struct dataent *files; | ||||
|   struct sumhashent *sumhashtab; | ||||
|   size_t sumused; | ||||
|   struct locrecent *primary_locrec = NULL; | ||||
|   struct nameent *primary_nameent = NULL; | ||||
| 
 | ||||
|   head = tmpl_ah->addr; | ||||
|   names = (struct nameent *) malloc (head->namehash_used | ||||
| 				     * sizeof (struct nameent)); | ||||
|   files = (struct dataent *) malloc (head->sumhash_used | ||||
| 				     * sizeof (struct dataent)); | ||||
|   if (names == NULL || files == NULL) | ||||
|     error (EXIT_FAILURE, errno, "could not allocate tables"); | ||||
| 
 | ||||
|   namehashtab = (struct namehashent *) ((char *) tmpl_ah->addr | ||||
| 					+ head->namehash_offset); | ||||
|   sumhashtab = (struct sumhashent *) ((char *) tmpl_ah->addr | ||||
| 				      + head->sumhash_offset); | ||||
| 
 | ||||
|   for (cnt = used = 0; cnt < head->namehash_size; ++cnt) | ||||
|     if (namehashtab[cnt].locrec_offset != 0) | ||||
|       { | ||||
| 	char * name; | ||||
| 	int i; | ||||
| 	assert (used < head->namehash_used); | ||||
|         name = tmpl_ah->addr + namehashtab[cnt].name_offset; | ||||
|         if (install_langs_count == 0) | ||||
|           { | ||||
| 	    /* Always intstall the entry.  */ | ||||
|             names[used].name = name; | ||||
|             names[used++].locrec | ||||
|                 = (struct locrecent *) ((char *) tmpl_ah->addr + | ||||
|                                         namehashtab[cnt].locrec_offset); | ||||
|           } | ||||
|         else | ||||
|           { | ||||
| 	    /* Only install the entry if the user asked for it via
 | ||||
| 	       --install-langs.  */ | ||||
|             for (i = 0; i < install_langs_count; i++) | ||||
|               { | ||||
| 		/* Add one for "_" and one for the null terminator.  */ | ||||
| 		size_t len = strlen (install_langs_list[i]) + 2; | ||||
| 		char *install_lang = (char *)xmalloc (len); | ||||
|                 strcpy (install_lang, install_langs_list[i]); | ||||
|                 if (strchr (install_lang, '_') == NULL) | ||||
|                   strcat (install_lang, "_"); | ||||
|                 if (strncmp (name, install_lang, strlen (install_lang)) == 0) | ||||
|                   { | ||||
|                     names[used].name = name; | ||||
|                     names[used++].locrec | ||||
| 		      = (struct locrecent *) ((char *)tmpl_ah->addr | ||||
| 					      + namehashtab[cnt].locrec_offset); | ||||
|                   } | ||||
| 		free (install_lang); | ||||
|               } | ||||
|           } | ||||
|       } | ||||
| 
 | ||||
|   /* Sort the names.  */ | ||||
|   qsort (names, used, sizeof (struct nameent), nameentcmp); | ||||
| 
 | ||||
|   for (cnt = sumused = 0; cnt < head->sumhash_size; ++cnt) | ||||
|     if (sumhashtab[cnt].file_offset != 0) | ||||
|       { | ||||
| 	assert (sumused < head->sumhash_used); | ||||
| 	files[sumused].sum = (const unsigned char *) sumhashtab[cnt].sum; | ||||
| 	files[sumused++].file_offset = sumhashtab[cnt].file_offset; | ||||
|       } | ||||
| 
 | ||||
|   /* Sort by file locations.  */ | ||||
|   qsort (files, sumused, sizeof (struct dataent), dataentcmp); | ||||
| 
 | ||||
|   /* Open the archive.  This call never returns if we cannot
 | ||||
|      successfully open the archive.  */ | ||||
|   ah.fname = NULL; | ||||
|   if (fname != NULL) | ||||
|     ah.fname = fname; | ||||
|   open_archive (&ah, false); | ||||
| 
 | ||||
|   if (primary != NULL) | ||||
|     { | ||||
|       for (cnt = 0; cnt < used; ++cnt) | ||||
| 	if (strcmp (names[cnt].name, primary) == 0) | ||||
| 	  break; | ||||
|       if (cnt < used) | ||||
| 	{ | ||||
| 	  locale_data_t data; | ||||
| 
 | ||||
| 	  compute_data (tmpl_ah, &names[cnt], sumused, files, data); | ||||
| 	  result |= add_locale_to_archive (&ah, primary, data, 0); | ||||
| 	  primary_locrec = names[cnt].locrec; | ||||
| 	  primary_nameent = &names[cnt]; | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   for (cnt = 0; cnt < used; ++cnt) | ||||
|     if (&names[cnt] == primary_nameent) | ||||
|       continue; | ||||
|     else if ((cnt > 0 && names[cnt - 1].locrec == names[cnt].locrec) | ||||
| 	     || names[cnt].locrec == primary_locrec) | ||||
|       { | ||||
| 	const char *oldname; | ||||
| 	struct namehashent *namehashent; | ||||
| 	uint32_t locrec_offset; | ||||
| 
 | ||||
| 	if (names[cnt].locrec == primary_locrec) | ||||
| 	  oldname = primary; | ||||
| 	else | ||||
| 	  oldname = names[cnt - 1].name; | ||||
| 	namehashent = insert_name (&ah, oldname, strlen (oldname), true); | ||||
| 	assert (namehashent->name_offset != 0); | ||||
| 	assert (namehashent->locrec_offset != 0); | ||||
| 	locrec_offset = namehashent->locrec_offset; | ||||
| 	add_alias (&ah, names[cnt].name, 0, oldname, &locrec_offset); | ||||
|       } | ||||
|     else | ||||
|       { | ||||
| 	locale_data_t data; | ||||
| 
 | ||||
| 	compute_data (tmpl_ah, &names[cnt], sumused, files, data); | ||||
| 	result |= add_locale_to_archive (&ah, names[cnt].name, data, 0); | ||||
|       } | ||||
| 
 | ||||
|   while (nlist-- > 0) | ||||
|     { | ||||
|       const char *fname = *list++; | ||||
|       size_t fnamelen = strlen (fname); | ||||
|       struct stat64 st; | ||||
|       DIR *dirp; | ||||
|       struct dirent64 *d; | ||||
|       int seen; | ||||
|       locale_data_t data; | ||||
|       int cnt; | ||||
| 
 | ||||
|       /* First see whether this really is a directory and whether it
 | ||||
| 	 contains all the require locale category files.  */ | ||||
|       if (stat64 (fname, &st) < 0) | ||||
| 	{ | ||||
| 	  error (0, 0, "stat of \"%s\" failed: %s: ignored", fname, | ||||
| 		 strerror (errno)); | ||||
| 	  continue; | ||||
| 	} | ||||
|       if (!S_ISDIR (st.st_mode)) | ||||
| 	{ | ||||
| 	  error (0, 0, "\"%s\" is no directory; ignored", fname); | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       dirp = opendir (fname); | ||||
|       if (dirp == NULL) | ||||
| 	{ | ||||
| 	  error (0, 0, "cannot open directory \"%s\": %s: ignored", | ||||
| 		 fname, strerror (errno)); | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       seen = 0; | ||||
|       while ((d = readdir64 (dirp)) != NULL) | ||||
| 	{ | ||||
| 	  for (cnt = 0; cnt < __LC_LAST; ++cnt) | ||||
| 	    if (cnt != LC_ALL) | ||||
| 	      if (strcmp (d->d_name, locnames[cnt]) == 0) | ||||
| 		{ | ||||
| 		  unsigned char d_type; | ||||
| 
 | ||||
| 		  /* We have an object of the required name.  If it's
 | ||||
| 		     a directory we have to look at a file with the | ||||
| 		     prefix "SYS_".  Otherwise we have found what we | ||||
| 		     are looking for.  */ | ||||
| #ifdef _DIRENT_HAVE_D_TYPE | ||||
| 		  d_type = d->d_type; | ||||
| 
 | ||||
| 		  if (d_type != DT_REG) | ||||
| #endif | ||||
| 		    { | ||||
| 		      char fullname[fnamelen + 2 * strlen (d->d_name) + 7]; | ||||
| 
 | ||||
| #ifdef _DIRENT_HAVE_D_TYPE | ||||
| 		      if (d_type == DT_UNKNOWN) | ||||
| #endif | ||||
| 			{ | ||||
| 			  strcpy (stpcpy (stpcpy (fullname, fname), "/"), | ||||
| 				  d->d_name); | ||||
| 
 | ||||
| 			  if (stat64 (fullname, &st) == -1) | ||||
| 			    /* We cannot stat the file, ignore it.  */ | ||||
| 			    break; | ||||
| 
 | ||||
| 			  d_type = IFTODT (st.st_mode); | ||||
| 			} | ||||
| 
 | ||||
| 		      if (d_type == DT_DIR) | ||||
| 			{ | ||||
| 			  /* We have to do more tests.  The file is a
 | ||||
| 			     directory and it therefore must contain a | ||||
| 			     regular file with the same name except a | ||||
| 			     "SYS_" prefix.  */ | ||||
| 			  char *t = stpcpy (stpcpy (fullname, fname), "/"); | ||||
| 			  strcpy (stpcpy (stpcpy (t, d->d_name), "/SYS_"), | ||||
| 				  d->d_name); | ||||
| 
 | ||||
| 			  if (stat64 (fullname, &st) == -1) | ||||
| 			    /* There is no SYS_* file or we cannot
 | ||||
| 			       access it.  */ | ||||
| 			    break; | ||||
| 
 | ||||
| 			  d_type = IFTODT (st.st_mode); | ||||
| 			} | ||||
| 		    } | ||||
| 
 | ||||
| 		  /* If we found a regular file (eventually after
 | ||||
| 		     following a symlink) we are successful.  */ | ||||
| 		  if (d_type == DT_REG) | ||||
| 		    ++seen; | ||||
| 		  break; | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|       closedir (dirp); | ||||
| 
 | ||||
|       if (seen != __LC_LAST - 1) | ||||
| 	{ | ||||
| 	  /* We don't have all locale category files.  Ignore the name.  */ | ||||
| 	  error (0, 0, "incomplete set of locale files in \"%s\"", | ||||
| 		 fname); | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       /* Add the files to the archive.  To do this we first compute
 | ||||
| 	 sizes and the MD5 sums of all the files.  */ | ||||
|       for (cnt = 0; cnt < __LC_LAST; ++cnt) | ||||
| 	if (cnt != LC_ALL) | ||||
| 	  { | ||||
| 	    char fullname[fnamelen + 2 * strlen (locnames[cnt]) + 7]; | ||||
| 	    int fd; | ||||
| 
 | ||||
| 	    strcpy (stpcpy (stpcpy (fullname, fname), "/"), locnames[cnt]); | ||||
| 	    fd = open64 (fullname, O_RDONLY); | ||||
| 	    if (fd == -1 || fstat64 (fd, &st) == -1) | ||||
| 	      { | ||||
| 		/* Cannot read the file.  */ | ||||
| 		if (fd != -1) | ||||
| 		  close (fd); | ||||
| 		break; | ||||
| 	      } | ||||
| 
 | ||||
| 	    if (S_ISDIR (st.st_mode)) | ||||
| 	      { | ||||
| 		char *t; | ||||
| 		close (fd); | ||||
| 		t = stpcpy (stpcpy (fullname, fname), "/"); | ||||
| 		strcpy (stpcpy (stpcpy (t, locnames[cnt]), "/SYS_"), | ||||
| 			locnames[cnt]); | ||||
| 
 | ||||
| 		fd = open64 (fullname, O_RDONLY); | ||||
| 		if (fd == -1 || fstat64 (fd, &st) == -1 | ||||
| 		    || !S_ISREG (st.st_mode)) | ||||
| 		  { | ||||
| 		    if (fd != -1) | ||||
| 		      close (fd); | ||||
| 		    break; | ||||
| 		  } | ||||
| 	      } | ||||
| 
 | ||||
| 	    /* Map the file.  */ | ||||
| 	    data[cnt].addr = mmap64 (NULL, st.st_size, PROT_READ, MAP_SHARED, | ||||
| 				     fd, 0); | ||||
| 	    if (data[cnt].addr == MAP_FAILED) | ||||
| 	      { | ||||
| 		/* Cannot map it.  */ | ||||
| 		close (fd); | ||||
| 		break; | ||||
| 	      } | ||||
| 
 | ||||
| 	    data[cnt].size = st.st_size; | ||||
| 	    __md5_buffer (data[cnt].addr, st.st_size, data[cnt].sum); | ||||
| 
 | ||||
| 	    /* We don't need the file descriptor anymore.  */ | ||||
| 	    close (fd); | ||||
| 	  } | ||||
| 
 | ||||
|       if (cnt != __LC_LAST) | ||||
| 	{ | ||||
| 	  while (cnt-- > 0) | ||||
| 	    if (cnt != LC_ALL) | ||||
| 	      munmap (data[cnt].addr, data[cnt].size); | ||||
| 
 | ||||
| 	  error (0, 0, "cannot read all files in \"%s\": ignored", fname); | ||||
| 
 | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       result |= add_locale_to_archive (&ah, basename (fname), data, 0); | ||||
| 
 | ||||
|       for (cnt = 0; cnt < __LC_LAST; ++cnt) | ||||
| 	if (cnt != LC_ALL) | ||||
| 	  munmap (data[cnt].addr, data[cnt].size); | ||||
|     } | ||||
| 
 | ||||
|   /* We are done.  */ | ||||
|   close_archive (&ah); | ||||
| 
 | ||||
|   return result; | ||||
| } | ||||
| 
 | ||||
| void usage() | ||||
| { | ||||
|   printf ("\
 | ||||
| Usage: build-locale-archive [OPTION]... [TEMPLATE-FILE] [ARCHIVE-FILE]\n\ | ||||
|  Builds a locale archive from a template file.\n\ | ||||
|  Options:\n\ | ||||
|   -h, --help                 Print this usage message.\n\ | ||||
|   -v, --verbose              Verbose execution.\n\ | ||||
|   -l, --install-langs=LIST   Only include locales given in LIST into the \n\ | ||||
|                              locale archive.  LIST is a colon separated list\n\ | ||||
|                              of locale prefixes, for example \"de:en:ja\".\n\
 | ||||
|                              The special argument \"all\" means to install\n\
 | ||||
|                              all languages and it must be present by itself.\n\ | ||||
|                              If \"all\" is present with any other language it\n\
 | ||||
|                              will be treated as the name of a locale.\n\ | ||||
|                              If the --install-langs option is missing, all\n\ | ||||
|                              locales are installed. The colon separated list\n\ | ||||
|                              can contain any strings matching the beginning of\n\ | ||||
|                              locale names.\n\ | ||||
|                              If a string does not contain a \"_\", it is added.\n\
 | ||||
|                              Examples:\n\ | ||||
|                                --install-langs=\"en\"\n\
 | ||||
|                                  installs en_US, en_US.iso88591,\n\ | ||||
|                                  en_US.iso885915, en_US.utf8,\n\ | ||||
|                                  en_GB ...\n\ | ||||
|                                --install-langs=\"en_US.utf8\"\n\
 | ||||
|                                  installs only en_US.utf8.\n\ | ||||
|                                --install-langs=\"ko\"\n\
 | ||||
|                                  installs ko_KR, ko_KR.euckr,\n\ | ||||
|                                  ko_KR.utf8 but *not* kok_IN\n\ | ||||
|                                  because \"ko\" does not contain\n\
 | ||||
|                                  \"_\" and it is silently added\n\
 | ||||
|                                --install-langs\"ko:kok\"\n\
 | ||||
|                                  installs ko_KR, ko_KR.euckr,\n\ | ||||
|                                  ko_KR.utf8, kok_IN, and\n\ | ||||
|                                  kok_IN.utf8.\n\ | ||||
|                                --install-langs=\"POSIX\" will\n\
 | ||||
|                                  installs *no* locales at all\n\ | ||||
|                                  because POSIX matches none of\n\ | ||||
|                                  the locales. Actually, any string\n\ | ||||
|                                  matching nothing will do that.\n\ | ||||
|                                  POSIX and C will always be\n\ | ||||
|                                  available because they are\n\ | ||||
|                                  builtin.\n\ | ||||
|                              Aliases are installed as well,\n\ | ||||
|                              i.e. --install-langs=\"de\"\n\
 | ||||
|                              will install not only every locale starting with\n\ | ||||
|                              \"de\" but also the aliases \"deutsch\"\n\
 | ||||
|                              and and \"german\" although the latter does not\n\
 | ||||
|                              start with \"de\".\n\
 | ||||
| \n\ | ||||
|   If the arguments TEMPLATE-FILE and ARCHIVE-FILE are not given the locations\n\ | ||||
|   where the glibc used expects these files are used by default.\n\ | ||||
| "); | ||||
| } | ||||
| 
 | ||||
| int main (int argc, char *argv[]) | ||||
| { | ||||
|   char path[4096]; | ||||
|   DIR *dirp; | ||||
|   struct dirent64 *d; | ||||
|   struct stat64 st; | ||||
|   char *list[16384], *primary; | ||||
|   char *lang; | ||||
|   int install_langs_count = 0; | ||||
|   int i; | ||||
|   char *install_langs_arg, *ila_start; | ||||
|   char **install_langs_list = NULL; | ||||
|   unsigned int cnt = 0; | ||||
|   struct locarhandle tmpl_ah; | ||||
|   char *new_locar_fname = NULL; | ||||
|   size_t loc_path_len = strlen (loc_path); | ||||
| 
 | ||||
|   while (1) | ||||
|     { | ||||
|       int c; | ||||
| 
 | ||||
|       static struct option long_options[] = | ||||
|         { | ||||
|             {"help",            no_argument,       0, 'h'}, | ||||
|             {"verbose",         no_argument,       0, 'v'}, | ||||
|             {"install-langs",   required_argument, 0, 'l'}, | ||||
|             {0, 0, 0, 0} | ||||
|         }; | ||||
|       /* getopt_long stores the option index here. */ | ||||
|       int option_index = 0; | ||||
| 
 | ||||
|       c = getopt_long (argc, argv, "vhl:", | ||||
|                        long_options, &option_index); | ||||
| 
 | ||||
|       /* Detect the end of the options. */ | ||||
|       if (c == -1) | ||||
|         break; | ||||
| 
 | ||||
|       switch (c) | ||||
|         { | ||||
|         case 0: | ||||
|           printf ("unknown option %s", long_options[option_index].name); | ||||
|           if (optarg) | ||||
|             printf (" with arg %s", optarg); | ||||
|           printf ("\n"); | ||||
|           usage (); | ||||
|           exit (1); | ||||
| 
 | ||||
|         case 'v': | ||||
|           verbose = 1; | ||||
|           be_quiet = 0; | ||||
|           break; | ||||
| 
 | ||||
|         case 'h': | ||||
|           usage (); | ||||
|           exit (0); | ||||
| 
 | ||||
|         case 'l': | ||||
|           install_langs_arg = ila_start = strdup (optarg); | ||||
|           /* If the argument to --install-lang is "all", do
 | ||||
|              not limit the list of languages to install and install | ||||
|              them all.  We do not support installing a single locale | ||||
| 	     called "all".  */ | ||||
| #define MAGIC_INSTALL_ALL "all" | ||||
|           if (install_langs_arg != NULL | ||||
| 	      && install_langs_arg[0] != '\0' | ||||
| 	      && !(strncmp(install_langs_arg, MAGIC_INSTALL_ALL, | ||||
| 			   strlen(MAGIC_INSTALL_ALL)) == 0 | ||||
| 		   && strlen (install_langs_arg) == 3)) | ||||
|             { | ||||
| 	      /* Count the number of languages we will install.  */ | ||||
|               while (true) | ||||
|                 { | ||||
|                   lang = strtok(install_langs_arg, ":;,"); | ||||
|                   if (lang == NULL) | ||||
|                     break; | ||||
|                   install_langs_count++; | ||||
|                   install_langs_arg = NULL; | ||||
|                 } | ||||
| 	      free (ila_start); | ||||
| 
 | ||||
| 	      /* Reject an entire string made up of delimiters.  */ | ||||
| 	      if (install_langs_count == 0) | ||||
| 		break; | ||||
| 
 | ||||
| 	      /* Copy the list.  */ | ||||
| 	      install_langs_list = (char **)xmalloc (sizeof(char *) * install_langs_count); | ||||
| 	      install_langs_arg = ila_start = strdup (optarg); | ||||
| 	      install_langs_count = 0; | ||||
| 	      while (true) | ||||
|                 { | ||||
|                   lang = strtok(install_langs_arg, ":;,"); | ||||
|                   if (lang == NULL) | ||||
|                     break; | ||||
|                   install_langs_list[install_langs_count] = lang; | ||||
| 		  install_langs_count++; | ||||
|                   install_langs_arg = NULL; | ||||
|                 } | ||||
|             } | ||||
|           break; | ||||
| 
 | ||||
|         case '?': | ||||
|           /* getopt_long already printed an error message. */ | ||||
|           usage (); | ||||
|           exit (0); | ||||
| 
 | ||||
|         default: | ||||
|           abort (); | ||||
|         } | ||||
|     } | ||||
|   tmpl_ah.fname = NULL; | ||||
|   if (optind < argc) | ||||
|     tmpl_ah.fname = argv[optind]; | ||||
|   if (optind + 1 < argc) | ||||
|     new_locar_fname = argv[optind + 1]; | ||||
|   if (verbose) | ||||
|     { | ||||
|       if (tmpl_ah.fname) | ||||
|         printf("input archive file specified on command line: %s\n", | ||||
|                tmpl_ah.fname); | ||||
|       else | ||||
|         printf("using default input archive file.\n"); | ||||
|       if (new_locar_fname) | ||||
|         printf("output archive file specified on command line: %s\n", | ||||
|                new_locar_fname); | ||||
|       else | ||||
|         printf("using default output archive file.\n"); | ||||
|     } | ||||
| 
 | ||||
|   dirp = opendir (loc_path); | ||||
|   if (dirp == NULL) | ||||
|     error (EXIT_FAILURE, errno, "cannot open directory \"%s\"", loc_path); | ||||
| 
 | ||||
|   open_tmpl_archive (&tmpl_ah); | ||||
| 
 | ||||
|   if (new_locar_fname) | ||||
|     unlink (new_locar_fname); | ||||
|   else | ||||
|     unlink (locar_file); | ||||
|   primary = getenv ("LC_ALL"); | ||||
|   if (primary == NULL) | ||||
|     primary = getenv ("LANG"); | ||||
|   if (primary != NULL) | ||||
|     { | ||||
|       if (strncmp (primary, "ja", 2) != 0 | ||||
| 	  && strncmp (primary, "ko", 2) != 0 | ||||
| 	  && strncmp (primary, "zh", 2) != 0) | ||||
| 	{ | ||||
| 	  char *ptr = malloc (strlen (primary) + strlen (".utf8") + 1), *p, *q; | ||||
| 	  /* This leads to invalid locales sometimes:
 | ||||
| 	     de_DE.iso885915@euro -> de_DE.utf8@euro */ | ||||
| 	  if (ptr != NULL) | ||||
| 	    { | ||||
| 	      p = ptr; | ||||
| 	      q = primary; | ||||
| 	      while (*q && *q != '.' && *q != '@') | ||||
| 		*p++ = *q++; | ||||
| 	      if (*q == '.') | ||||
| 		while (*q && *q != '@') | ||||
| 		  q++; | ||||
| 	      p = stpcpy (p, ".utf8"); | ||||
| 	      strcpy (p, q); | ||||
| 	      primary = ptr; | ||||
| 	    } | ||||
| 	  else | ||||
| 	    primary = NULL; | ||||
| 	} | ||||
|     } | ||||
| 
 | ||||
|   memcpy (path, loc_path, loc_path_len); | ||||
| 
 | ||||
|   while ((d = readdir64 (dirp)) != NULL) | ||||
|     { | ||||
|       if (strcmp (d->d_name, ".") == 0 || strcmp (d->d_name, "..") == 0) | ||||
| 	continue; | ||||
|       if (strchr (d->d_name, '_') == NULL) | ||||
| 	continue; | ||||
| 
 | ||||
|       size_t d_name_len = strlen (d->d_name); | ||||
|       if (loc_path_len + d_name_len + 1 > sizeof (path)) | ||||
| 	{ | ||||
| 	  error (0, 0, "too long filename \"%s\"", d->d_name); | ||||
| 	  continue; | ||||
| 	} | ||||
| 
 | ||||
|       memcpy (path + loc_path_len, d->d_name, d_name_len + 1); | ||||
|       if (stat64 (path, &st) < 0) | ||||
| 	{ | ||||
| 	  error (0, errno, "cannot stat \"%s\"", path); | ||||
| 	  continue; | ||||
| 	} | ||||
|       if (! S_ISDIR (st.st_mode)) | ||||
| 	continue; | ||||
|       if (cnt == 16384) | ||||
| 	{ | ||||
| 	  error (0, 0, "too many directories in \"%s\"", loc_path); | ||||
| 	  break; | ||||
| 	} | ||||
|       list[cnt] = strdup (path); | ||||
|       if (list[cnt] == NULL) | ||||
| 	{ | ||||
| 	  error (0, errno, "cannot add file to list \"%s\"", path); | ||||
| 	  continue; | ||||
| 	} | ||||
|       if (primary != NULL && cnt > 0 && strcmp (primary, d->d_name) == 0) | ||||
| 	{ | ||||
| 	  char *p = list[0]; | ||||
| 	  list[0] = list[cnt]; | ||||
| 	  list[cnt] = p; | ||||
| 	} | ||||
|       cnt++; | ||||
|     } | ||||
|   closedir (dirp); | ||||
|   /* Store the archive to the file specified as the second argument on the
 | ||||
|      command line or the default locale archive.  */ | ||||
|   fill_archive (&tmpl_ah, new_locar_fname, | ||||
|                 install_langs_count, install_langs_list, | ||||
|                 cnt, list, primary); | ||||
|   close_archive (&tmpl_ah); | ||||
|   truncate (tmpl_file, 0); | ||||
|   if (install_langs_count > 0) | ||||
|     { | ||||
|       free (ila_start); | ||||
|       free (install_langs_list); | ||||
|     } | ||||
|   char *tz_argv[] = { "/usr/sbin/tzdata-update", NULL }; | ||||
|   execve (tz_argv[0], (char *const *)tz_argv, (char *const *)&tz_argv[1]); | ||||
|   exit (0); | ||||
| } | ||||
							
								
								
									
										25
									
								
								SOURCES/glibc-asflags.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								SOURCES/glibc-asflags.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Wed Jul 4 16:16:57 2018 +0200 | ||||
| 
 | ||||
|     Makeconfig (ASFLAGS): Always append required assembler flags. | ||||
| 
 | ||||
| Submitted upstream here: | ||||
| 
 | ||||
|   https://sourceware.org/ml/libc-alpha/2018-07/msg00077.html | ||||
| 
 | ||||
| Otherwise, we lose essential flags such as -Wa,--noexecstack due to | ||||
| the way += works in make due to the ASFLAGS command line override. | ||||
| 
 | ||||
| diff --git a/Makeconfig b/Makeconfig
 | ||||
| index b0b27f0113ac18b8..92e76d6200bbcd5b 100644
 | ||||
| --- a/Makeconfig
 | ||||
| +++ b/Makeconfig
 | ||||
| @@ -1047,7 +1047,7 @@ endif
 | ||||
|  ifndef ASFLAGS | ||||
|  ASFLAGS := $(filter -g% -fdebug-prefix-map=%,$(CFLAGS)) | ||||
|  endif | ||||
| -ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
 | ||||
| +override ASFLAGS += -Werror=undef $(ASFLAGS-config) $(asflags-cpu)
 | ||||
|   | ||||
|  ifndef BUILD_CC | ||||
|  BUILD_CC = $(CC) | ||||
							
								
								
									
										153
									
								
								SOURCES/glibc-bench-compare
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										153
									
								
								SOURCES/glibc-bench-compare
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,153 @@ | ||||
| #!/usr/bin/bash | ||||
| # This script can be invoked as follows: | ||||
| # | ||||
| # glibc-bench-compare [options] <BUILD> [BUILD] | ||||
| # | ||||
| # Options may be one of the following: | ||||
| # | ||||
| # -t		The BUILD arguments are task ids and not a version-release string | ||||
| # -a ARCH	Do comparison for ARCH architecture | ||||
| # | ||||
| # If any of the above options are given, both BUILD arguments must be given. | ||||
| # Otherwise, if only one BUILD is specified, then it is compared against the | ||||
| # installed glibc. | ||||
| 
 | ||||
| # Silence the pushd/popd messages | ||||
| pushd() { | ||||
| 	command pushd "$@" > /dev/null 2>&1 | ||||
| } | ||||
| 
 | ||||
| popd() { | ||||
| 	command popd "$@" > /dev/null 2>&1 | ||||
| } | ||||
| 
 | ||||
| # Clean up any downloaded files before we exit | ||||
| trap "rm -rf /tmp/glibc-bench-compare.$BASHPID.*" EXIT | ||||
| 
 | ||||
| task=0 | ||||
| arch=$(uname -i) | ||||
| options=0 | ||||
| path=0 | ||||
| installed= | ||||
| 
 | ||||
| # Look for any commandline options | ||||
| while getopts ":tpa:" opt; do | ||||
| 	case $opt in | ||||
| 		p) | ||||
| 		path=1 | ||||
| 		;; | ||||
| 		t) | ||||
| 		task=1 | ||||
| 		options=1 | ||||
| 		echo "Not implemented." | ||||
| 		exit 1 | ||||
| 		;; | ||||
| 		a) | ||||
| 		arch=$OPTARG | ||||
| 		options=1 | ||||
| 		;; | ||||
| 		*) | ||||
| 		;; | ||||
| 	esac | ||||
| done | ||||
| 
 | ||||
| # Done, now shift all option arguments out. | ||||
| shift $((OPTIND-1)) | ||||
| 
 | ||||
| if [ $# -gt 2 ] || [ $# -eq 0 ] || [ $# -lt 2 -a $options -eq 1 ]; then | ||||
| 	echo "Usage: $0 [OPTIONS] <old> [new]" | ||||
| 	echo | ||||
| 	echo "OPTIONS:" | ||||
| 	echo -e "\t-t\tCompare two brew tasks" | ||||
| 	echo -e "\t-a ARCH\tGet rpms for the ARCH architecture" | ||||
| 	echo -e "\t-p\tCompare built rpms in two paths." | ||||
| 	echo -e "\t\tThis minimally needs glibc, glibc-common and glibc-benchtests" | ||||
| 	exit 1 | ||||
| fi | ||||
| 
 | ||||
| if [ -z $2 ]; then | ||||
| 	new="$1" | ||||
| 	old=$(rpm --queryformat "%{VERSION}-%{RELEASE}\n" -q glibc | head -1) | ||||
| 	installed=$old | ||||
| else | ||||
| 	new="$2" | ||||
| 	old="$1" | ||||
| fi | ||||
| 
 | ||||
| decompress_rpms() { | ||||
| 	# We were given a path to the rpms.  Figure out the version-release and | ||||
| 	# decompress the rpms. | ||||
| 	if [ -n $1 ]; then | ||||
| 		vr=$(rpm --queryformat="%{VERSION}-%{RELEASE}" -qp $1/glibc-2*.rpm | head -1) | ||||
| 		mkdir $vr && pushd $vr | ||||
| 	fi | ||||
| 
 | ||||
| 	for r in $1*.rpm; do | ||||
| 		( rpm2cpio $r | cpio -di ) > /dev/null | ||||
| 	done | ||||
| 
 | ||||
| 	if [ -n $1 ]; then | ||||
| 		popd | ||||
| 		echo $vr | ||||
| 	fi | ||||
| } | ||||
| 
 | ||||
| # Get rpms for a build and decompress them | ||||
| get_build() { | ||||
| 	echo "Processing build $1" | ||||
| 	mkdir $1 && pushd $1 | ||||
| 	brew buildinfo "glibc-$1" | | ||||
| 	sed -n -e "s|/mnt/koji\(.\+$arch.\+\)|http://kojipkgs.fedoraproject.org\1|p" | | ||||
| 	while read url; do | ||||
| 		echo "Downloading $url" | ||||
| 		wget -q $url | ||||
| 	done | ||||
| 	decompress_rpms | ||||
| 
 | ||||
| 	echo "Removing rpms" | ||||
| 	rm -f $1/*.rpm | ||||
| 
 | ||||
| 	popd | ||||
| } | ||||
| 
 | ||||
| # Run benchmarks for a build | ||||
| run_bench() { | ||||
| 	if [ -z $1 ]; then | ||||
| 		make DETAILED=1 ver=$installed prefix= -f /usr/libexec/glibc-benchtests/bench.mk bench | ||||
| 	else | ||||
| 		make DETAILED=1 ver=$1 prefix=$PWD -f $1/usr/libexec/glibc-benchtests/bench.mk bench | ||||
| 	fi | ||||
| } | ||||
| 
 | ||||
| # Get absolute paths if needed, since we will change into the working directory | ||||
| # next. | ||||
| if [ $path -eq 1 ]; then | ||||
| 	old_path=$(realpath $old)/ | ||||
| 	new_path=$(realpath $new)/ | ||||
| fi | ||||
| 
 | ||||
| tmpdir=$(mktemp -p /tmp -d glibc-bench-compare.$$.XXXX) | ||||
| pushd $tmpdir | ||||
| 
 | ||||
| # Get both builds. | ||||
| if [ $path -eq 0 ]; then | ||||
| 	if [ -z $installed ]; then | ||||
| 		get_build $old | ||||
| 	fi | ||||
| 	get_build $new | ||||
| else | ||||
| 	old=$(decompress_rpms $old_path) | ||||
| 	new=$(decompress_rpms $new_path) | ||||
| fi | ||||
| 
 | ||||
| # make bench for each of those. | ||||
| if [ -z $installed ]; then | ||||
| 	run_bench $old | ||||
| else | ||||
| 	run_bench | ||||
| fi | ||||
| run_bench $new | ||||
| 
 | ||||
| # Now run the comparison script. | ||||
| $old/usr/libexec/glibc-benchtests/compare_bench.py $old/usr/libexec/glibc-benchtests/benchout.schema.json \ | ||||
| 	bench.$old.out bench.$new.out | ||||
							
								
								
									
										286
									
								
								SOURCES/glibc-c-utf8-locale.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										286
									
								
								SOURCES/glibc-c-utf8-locale.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,286 @@ | ||||
| Short description: Add C.UTF-8 support. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-submitted | ||||
| 
 | ||||
| This patch needs to upstream as part of Carlos O'Donell | ||||
| <carlos@redhat.com>'s work on enabling upstream C.UTF-8 support. This | ||||
| work is currently blocked on cleaning up the test results to prove that | ||||
| full code-point sorting is working as intended. | ||||
| 
 | ||||
| Note that this patch does not provide full code-point sorting as | ||||
| expected. | ||||
| 
 | ||||
| This patch needs to upstream as soon as possible since it would be nice | ||||
| to have this in F29 and fixed. | ||||
| 
 | ||||
| From 2eda7b462b415105f5a05c1323372d4e39d46439 Mon Sep 17 00:00:00 2001 | ||||
| From: Mike FABIAN <mfabian@redhat.com> | ||||
| Date: Mon, 10 Aug 2015 15:58:12 +0200 | ||||
| Subject: [PATCH] Add a C.UTF-8 locale | ||||
| 
 | ||||
| ---
 | ||||
|  localedata/SUPPORTED |   1 + | ||||
|  localedata/locales/C | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ | ||||
|  2 files changed, 239 insertions(+) | ||||
|  create mode 100644 localedata/locales/C | ||||
| 
 | ||||
| diff --git a/localedata/SUPPORTED b/localedata/SUPPORTED
 | ||||
| index 8ca023e..2a78391 100644
 | ||||
| --- a/localedata/SUPPORTED
 | ||||
| +++ b/localedata/SUPPORTED
 | ||||
| @@ -1,6 +1,7 @@
 | ||||
|  # This file names the currently supported and somewhat tested locales. | ||||
|  # If you have any additions please file a glibc bug report. | ||||
|  SUPPORTED-LOCALES=\ | ||||
| +C.UTF-8/UTF-8 \
 | ||||
|  aa_DJ.UTF-8/UTF-8 \ | ||||
|  aa_DJ/ISO-8859-1 \ | ||||
|  aa_ER/UTF-8 \ | ||||
| diff --git a/localedata/locales/C b/localedata/locales/C
 | ||||
| new file mode 100644 | ||||
| index 0000000..fdf460e
 | ||||
| --- /dev/null
 | ||||
| +++ b/localedata/locales/C
 | ||||
| @@ -0,0 +1,238 @@
 | ||||
| +escape_char /
 | ||||
| +comment_char %
 | ||||
| +% Locale for C locale in UTF-8
 | ||||
| +
 | ||||
| +LC_IDENTIFICATION
 | ||||
| +title      "C locale"
 | ||||
| +source     ""
 | ||||
| +address    ""
 | ||||
| +contact    ""
 | ||||
| +email      "mfabian@redhat.com"
 | ||||
| +tel        ""
 | ||||
| +fax        ""
 | ||||
| +language   "C"
 | ||||
| +territory  ""
 | ||||
| +revision   "1.0"
 | ||||
| +date       "2015-08-10"
 | ||||
| +%
 | ||||
| +category  "i18n:2012";LC_IDENTIFICATION
 | ||||
| +category  "i18n:2012";LC_CTYPE
 | ||||
| +category  "i18n:2012";LC_COLLATE
 | ||||
| +category  "i18n:2012";LC_TIME
 | ||||
| +category  "i18n:2012";LC_NUMERIC
 | ||||
| +category  "i18n:2012";LC_MONETARY
 | ||||
| +category  "i18n:2012";LC_MESSAGES
 | ||||
| +category  "i18n:2012";LC_PAPER
 | ||||
| +category  "i18n:2012";LC_NAME
 | ||||
| +category  "i18n:2012";LC_ADDRESS
 | ||||
| +category  "i18n:2012";LC_TELEPHONE
 | ||||
| +category  "i18n:2012";LC_MEASUREMENT
 | ||||
| +END LC_IDENTIFICATION
 | ||||
| +
 | ||||
| +LC_CTYPE
 | ||||
| +copy "i18n"
 | ||||
| +
 | ||||
| +translit_start
 | ||||
| +include "translit_combining";""
 | ||||
| +translit_end
 | ||||
| +
 | ||||
| +END LC_CTYPE
 | ||||
| +
 | ||||
| +LC_COLLATE
 | ||||
| +order_start forward
 | ||||
| +<U0000>
 | ||||
| +..
 | ||||
| +<UFFFF>
 | ||||
| +<U10000>
 | ||||
| +..
 | ||||
| +<U1FFFF>
 | ||||
| +<U20000>
 | ||||
| +..
 | ||||
| +<U2FFFF>
 | ||||
| +<UE0000>
 | ||||
| +..
 | ||||
| +<UEFFFF>
 | ||||
| +<UF0000>
 | ||||
| +..
 | ||||
| +<UFFFFF>
 | ||||
| +<U100000>
 | ||||
| +..
 | ||||
| +<U10FFFF>
 | ||||
| +UNDEFINED
 | ||||
| +order_end
 | ||||
| +END LC_COLLATE
 | ||||
| +
 | ||||
| +LC_MONETARY
 | ||||
| +% This is the 14652 i18n fdcc-set definition for
 | ||||
| +% the LC_MONETARY category
 | ||||
| +% (except for the int_curr_symbol and currency_symbol, they are empty in
 | ||||
| +% the 14652 i18n fdcc-set definition and also empty in
 | ||||
| +% glibc/locale/C-monetary.c. But localedef complains in that case).
 | ||||
| +%
 | ||||
| +% Using "USD" for int_curr_symbol. But maybe "XXX" would be better?
 | ||||
| +% XXX is "No currency" (https://en.wikipedia.org/wiki/ISO_4217)
 | ||||
| +int_curr_symbol     "<U0055><U0053><U0044><U0020>"
 | ||||
| +% Using "$" for currency_symbol. But maybe <U00A4> would be better?
 | ||||
| +% U+00A4 is the "generic currency symbol"
 | ||||
| +% (https://en.wikipedia.org/wiki/Currency_sign_%28typography%29)
 | ||||
| +currency_symbol     "<U0024>"
 | ||||
| +mon_decimal_point   "<U002E>"
 | ||||
| +mon_thousands_sep   ""
 | ||||
| +mon_grouping        -1
 | ||||
| +positive_sign       ""
 | ||||
| +negative_sign       "<U002D>"
 | ||||
| +int_frac_digits     -1
 | ||||
| +frac_digits         -1
 | ||||
| +p_cs_precedes       -1
 | ||||
| +int_p_sep_by_space  -1
 | ||||
| +p_sep_by_space      -1
 | ||||
| +n_cs_precedes       -1
 | ||||
| +int_n_sep_by_space  -1
 | ||||
| +n_sep_by_space      -1
 | ||||
| +p_sign_posn         -1
 | ||||
| +n_sign_posn         -1
 | ||||
| +%
 | ||||
| +END LC_MONETARY
 | ||||
| +
 | ||||
| +LC_NUMERIC
 | ||||
| +% This is the POSIX Locale definition for
 | ||||
| +% the LC_NUMERIC category.
 | ||||
| +%
 | ||||
| +decimal_point   "<U002E>"
 | ||||
| +thousands_sep   ""
 | ||||
| +grouping        -1
 | ||||
| +END LC_NUMERIC
 | ||||
| +
 | ||||
| +LC_TIME
 | ||||
| +% This is the POSIX Locale definition for
 | ||||
| +% the LC_TIME category.
 | ||||
| +%
 | ||||
| +% Abbreviated weekday names (%a)
 | ||||
| +abday       "<U0053><U0075><U006E>";"<U004D><U006F><U006E>";/
 | ||||
| +            "<U0054><U0075><U0065>";"<U0057><U0065><U0064>";/
 | ||||
| +            "<U0054><U0068><U0075>";"<U0046><U0072><U0069>";/
 | ||||
| +            "<U0053><U0061><U0074>"
 | ||||
| +
 | ||||
| +% Full weekday names (%A)
 | ||||
| +day         "<U0053><U0075><U006E><U0064><U0061><U0079>";/
 | ||||
| +            "<U004D><U006F><U006E><U0064><U0061><U0079>";/
 | ||||
| +            "<U0054><U0075><U0065><U0073><U0064><U0061><U0079>";/
 | ||||
| +            "<U0057><U0065><U0064><U006E><U0065><U0073><U0064><U0061><U0079>";/
 | ||||
| +            "<U0054><U0068><U0075><U0072><U0073><U0064><U0061><U0079>";/
 | ||||
| +            "<U0046><U0072><U0069><U0064><U0061><U0079>";/
 | ||||
| +            "<U0053><U0061><U0074><U0075><U0072><U0064><U0061><U0079>"
 | ||||
| +
 | ||||
| +% Abbreviated month names (%b)
 | ||||
| +abmon       "<U004A><U0061><U006E>";"<U0046><U0065><U0062>";/
 | ||||
| +            "<U004D><U0061><U0072>";"<U0041><U0070><U0072>";/
 | ||||
| +            "<U004D><U0061><U0079>";"<U004A><U0075><U006E>";/
 | ||||
| +            "<U004A><U0075><U006C>";"<U0041><U0075><U0067>";/
 | ||||
| +            "<U0053><U0065><U0070>";"<U004F><U0063><U0074>";/
 | ||||
| +            "<U004E><U006F><U0076>";"<U0044><U0065><U0063>"
 | ||||
| +
 | ||||
| +% Full month names (%B)
 | ||||
| +mon         "<U004A><U0061><U006E><U0075><U0061><U0072><U0079>";/
 | ||||
| +            "<U0046><U0065><U0062><U0072><U0075><U0061><U0072><U0079>";/
 | ||||
| +            "<U004D><U0061><U0072><U0063><U0068>";/
 | ||||
| +            "<U0041><U0070><U0072><U0069><U006C>";/
 | ||||
| +            "<U004D><U0061><U0079>";/
 | ||||
| +            "<U004A><U0075><U006E><U0065>";/
 | ||||
| +            "<U004A><U0075><U006C><U0079>";/
 | ||||
| +            "<U0041><U0075><U0067><U0075><U0073><U0074>";/
 | ||||
| +            "<U0053><U0065><U0070><U0074><U0065><U006D><U0062><U0065><U0072>";/
 | ||||
| +            "<U004F><U0063><U0074><U006F><U0062><U0065><U0072>";/
 | ||||
| +            "<U004E><U006F><U0076><U0065><U006D><U0062><U0065><U0072>";/
 | ||||
| +            "<U0044><U0065><U0063><U0065><U006D><U0062><U0065><U0072>"
 | ||||
| +
 | ||||
| +% Week description, consists of three fields:
 | ||||
| +% 1. Number of days in a week.
 | ||||
| +% 2. Gregorian date that is a first weekday (19971130 for Sunday, 19971201 for Monday).
 | ||||
| +% 3. The weekday number to be contained in the first week of the year.
 | ||||
| +%
 | ||||
| +% ISO 8601 conforming applications should use the values 7, 19971201 (a
 | ||||
| +% Monday), and 4 (Thursday), respectively.
 | ||||
| +week    7;19971201;4
 | ||||
| +first_weekday	1
 | ||||
| +first_workday	1
 | ||||
| +
 | ||||
| +% Appropriate date and time representation (%c)
 | ||||
| +%	"%a %b %e %H:%M:%S %Y"
 | ||||
| +d_t_fmt "<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0059>"
 | ||||
| +
 | ||||
| +% Appropriate date representation (%x)
 | ||||
| +%	"%m/%d/%y"
 | ||||
| +d_fmt   "<U0025><U006D><U002F><U0025><U0064><U002F><U0025><U0079>"
 | ||||
| +
 | ||||
| +% Appropriate time representation (%X)
 | ||||
| +%	"%H:%M:%S"
 | ||||
| +t_fmt   "<U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053>"
 | ||||
| +
 | ||||
| +% Appropriate AM/PM time representation (%r)
 | ||||
| +%	"%I:%M:%S %p"
 | ||||
| +t_fmt_ampm "<U0025><U0049><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U0070>"
 | ||||
| +
 | ||||
| +% Equivalent of AM/PM (%p)      "AM"/"PM"
 | ||||
| +%
 | ||||
| +am_pm	"<U0041><U004D>";"<U0050><U004D>"
 | ||||
| +
 | ||||
| +% Appropriate date representation (date(1))   "%a %b %e %H:%M:%S %Z %Y"
 | ||||
| +date_fmt	"<U0025><U0061><U0020><U0025><U0062><U0020><U0025><U0065><U0020><U0025><U0048><U003A><U0025><U004D><U003A><U0025><U0053><U0020><U0025><U005A><U0020><U0025><U0059>"
 | ||||
| +END LC_TIME
 | ||||
| +
 | ||||
| +LC_MESSAGES
 | ||||
| +% This is the POSIX Locale definition for
 | ||||
| +% the LC_NUMERIC category.
 | ||||
| +%
 | ||||
| +yesexpr "<U005E><U005B><U0079><U0059><U005D>"
 | ||||
| +noexpr  "<U005E><U005B><U006E><U004E><U005D>"
 | ||||
| +yesstr  "<U0059><U0065><U0073>"
 | ||||
| +nostr   "<U004E><U006F>"
 | ||||
| +END LC_MESSAGES
 | ||||
| +
 | ||||
| +LC_PAPER
 | ||||
| +% This is the ISO/IEC 14652 "i18n" definition for
 | ||||
| +% the LC_PAPER category.
 | ||||
| +% (A4 paper, this is also used in the built in C/POSIX
 | ||||
| +% locale in glibc/locale/C-paper.c)
 | ||||
| +height   297
 | ||||
| +width    210
 | ||||
| +END LC_PAPER
 | ||||
| +
 | ||||
| +LC_NAME
 | ||||
| +% This is the ISO/IEC 14652 "i18n" definition for
 | ||||
| +% the LC_NAME category.
 | ||||
| +% "%p%t%g%t%m%t%f"
 | ||||
| +% (also used in the built in C/POSIX locale in glibc/locale/C-name.c)
 | ||||
| +name_fmt    "<U0025><U0070><U0025><U0074><U0025><U0067><U0025><U0074>/
 | ||||
| +<U0025><U006D><U0025><U0074><U0025><U0066>"
 | ||||
| +END LC_NAME
 | ||||
| +
 | ||||
| +LC_ADDRESS
 | ||||
| +% This is the ISO/IEC 14652 "i18n" definition for
 | ||||
| +% the LC_ADDRESS category.
 | ||||
| +% "%a%N%f%N%d%N%b%N%s %h %e %r%N%C-%z %T%N%c%N"
 | ||||
| +% (also used in the built in C/POSIX locale in glibc/locale/C-address.c)
 | ||||
| +postal_fmt    "<U0025><U0061><U0025><U004E><U0025><U0066><U0025><U004E>/
 | ||||
| +<U0025><U0064><U0025><U004E><U0025><U0062><U0025><U004E><U0025><U0073>/
 | ||||
| +<U0020><U0025><U0068><U0020><U0025><U0065><U0020><U0025><U0072><U0025>/
 | ||||
| +<U004E><U0025><U0043><U002D><U0025><U007A><U0020><U0025><U0054><U0025>/
 | ||||
| +<U004E><U0025><U0063><U0025><U004E>"
 | ||||
| +END LC_ADDRESS
 | ||||
| +
 | ||||
| +LC_TELEPHONE
 | ||||
| +% This is the ISO/IEC 14652 "i18n" definition for
 | ||||
| +% the LC_TELEPHONE category.
 | ||||
| +% "+%c %a %l"
 | ||||
| +tel_int_fmt    "<U002B><U0025><U0063><U0020><U0025><U0061><U0020><U0025>/
 | ||||
| +<U006C>"
 | ||||
| +% (also used in the built in C/POSIX locale in glibc/locale/C-telephone.c)
 | ||||
| +END LC_TELEPHONE
 | ||||
| +
 | ||||
| +LC_MEASUREMENT
 | ||||
| +% This is the ISO/IEC 14652 "i18n" definition for
 | ||||
| +% the LC_MEASUREMENT category.
 | ||||
| +% (same as in the built in C/POSIX locale in glibc/locale/C-measurement.c)
 | ||||
| +%metric
 | ||||
| +measurement    1
 | ||||
| +END LC_MEASUREMENT
 | ||||
| +
 | ||||
| -- 
 | ||||
| 2.4.3 | ||||
| 
 | ||||
							
								
								
									
										15
									
								
								SOURCES/glibc-cs-path.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								SOURCES/glibc-cs-path.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,15 @@ | ||||
| Short description: Adjust CS_PATH return value. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| In Fedora we should return only /usr/bin because /bin is just a symlink | ||||
| to /usr/bin after MoveToUsr transition (which glibc has not really | ||||
| completed). | ||||
| 
 | ||||
| diff -pruN a/sysdeps/unix/confstr.h b/sysdeps/unix/confstr.h
 | ||||
| --- a/sysdeps/unix/confstr.h	2012-12-25 08:32:13.000000000 +0530
 | ||||
| +++ b/sysdeps/unix/confstr.h	2014-09-05 20:02:55.698275219 +0530
 | ||||
| @@ -1 +1 @@
 | ||||
| -#define	CS_PATH	"/bin:/usr/bin"
 | ||||
| +#define	CS_PATH	"/usr/bin"
 | ||||
							
								
								
									
										91
									
								
								SOURCES/glibc-fedora-__libc_multiple_libcs.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								SOURCES/glibc-fedora-__libc_multiple_libcs.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,91 @@ | ||||
| Short description: Cleanup use of _dl_starting_up. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: https://sourceware.org/ml/libc-alpha/2014-02/msg00589.html | ||||
| 
 | ||||
| Upstream discussions: | ||||
| https://sourceware.org/ml/libc-alpha/2014-02/msg00580.html | ||||
| 
 | ||||
| Based on the following commit: | ||||
| ~~~ | ||||
| From 16552c01a66633c9e412984d9d92616bd4e5303c Mon Sep 17 00:00:00 2001 | ||||
| From: Andreas Schwab <schwab@redhat.com> | ||||
| Date: Fri, 11 Jun 2010 11:04:11 +0200 | ||||
| Subject: [PATCH] Properly set __libc_multiple_libcs | ||||
| 
 | ||||
| 	* elf/rtld.c (_dl_starting_up): Always define. | ||||
| 	(dl_main): Always set _dl_starting_up. | ||||
| 	* elf/dl-support.c (_dl_starting_up): Always define. | ||||
| 	* elf/dl-init.c (_dl_init): Always clear _dl_starting_up. | ||||
| 
 | ||||
| ---
 | ||||
| ChangeLog        |    7 +++++++ | ||||
| elf/dl-init.c    |    4 ---- | ||||
| elf/dl-support.c |    2 -- | ||||
| elf/rtld.c       |    4 ---- | ||||
| 4 files changed, 7 insertions(+), 10 deletions(-) | ||||
| ~~~ | ||||
| 
 | ||||
| This patch needs to go upstream to get cleaned up, but has always involed | ||||
| analysis of the GNU/Hurd parts of the change and that stalled out, but | ||||
| perhaps with build-many-glibcs we can now test these changes more easily. | ||||
| 
 | ||||
| Index: b/elf/dl-init.c
 | ||||
| ===================================================================
 | ||||
| --- a/elf/dl-init.c
 | ||||
| +++ b/elf/dl-init.c
 | ||||
| @@ -119,8 +119,6 @@ _dl_init (struct link_map *main_map, int
 | ||||
|    while (i-- > 0) | ||||
|      call_init (main_map->l_initfini[i], argc, argv, env); | ||||
|   | ||||
| -#ifndef HAVE_INLINED_SYSCALLS
 | ||||
|    /* Finished starting up.  */ | ||||
|    _dl_starting_up = 0; | ||||
| -#endif
 | ||||
|  } | ||||
| Index: b/elf/dl-support.c
 | ||||
| ===================================================================
 | ||||
| --- a/elf/dl-support.c
 | ||||
| +++ b/elf/dl-support.c
 | ||||
| @@ -117,10 +117,8 @@ struct r_scope_elem _dl_initial_searchli
 | ||||
|      .r_nlist = 1, | ||||
|    }; | ||||
|   | ||||
| -#ifndef HAVE_INLINED_SYSCALLS
 | ||||
|  /* Nonzero during startup.  */ | ||||
|  int _dl_starting_up = 1; | ||||
| -#endif
 | ||||
|   | ||||
|  /* Random data provided by the kernel.  */ | ||||
|  void *_dl_random; | ||||
| Index: b/elf/rtld.c
 | ||||
| ===================================================================
 | ||||
| --- a/elf/rtld.c
 | ||||
| +++ b/elf/rtld.c
 | ||||
| @@ -214,7 +214,6 @@ audit_list_iter_next (struct audit_list_
 | ||||
|    return iter->previous->name; | ||||
|  } | ||||
|   | ||||
| -#ifndef HAVE_INLINED_SYSCALLS
 | ||||
|  /* Set nonzero during loading and initialization of executable and | ||||
|     libraries, cleared before the executable's entry point runs.  This | ||||
|     must not be initialized to nonzero, because the unused dynamic | ||||
| @@ -224,7 +223,6 @@ audit_list_iter_next (struct audit_list_
 | ||||
|     never be called.  */ | ||||
|  int _dl_starting_up = 0; | ||||
|  rtld_hidden_def (_dl_starting_up) | ||||
| -#endif
 | ||||
|   | ||||
|  /* This is the structure which defines all variables global to ld.so | ||||
|     (except those which cannot be added for some reason).  */ | ||||
| @@ -898,10 +896,8 @@ dl_main (const ElfW(Phdr) *phdr,
 | ||||
|    /* Process the environment variable which control the behaviour.  */ | ||||
|    process_envvars (&mode); | ||||
|   | ||||
| -#ifndef HAVE_INLINED_SYSCALLS
 | ||||
|    /* Set up a flag which tells we are just starting.  */ | ||||
|    _dl_starting_up = 1; | ||||
| -#endif
 | ||||
|   | ||||
|    if (*user_entry == (ElfW(Addr)) ENTRY_POINT) | ||||
|      { | ||||
							
								
								
									
										61
									
								
								SOURCES/glibc-fedora-linux-tcsetattr.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								SOURCES/glibc-fedora-linux-tcsetattr.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| Short description: Fedora-specific workaround for kernel pty bug. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-submitted | ||||
| 
 | ||||
| This is a Fedora-specific workaround for a kernel bug where calling | ||||
| ioctl on a pty will silently ignore the invalid c_cflag. The | ||||
| workaround is to use TCGETS to verify the setting matches. This is | ||||
| not upstream and needs to either be removed or submitted upstream | ||||
| after analysis. | ||||
| 
 | ||||
| Index: b/sysdeps/unix/sysv/linux/tcsetattr.c
 | ||||
| ===================================================================
 | ||||
| --- a/sysdeps/unix/sysv/linux/tcsetattr.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/tcsetattr.c
 | ||||
| @@ -45,6 +45,7 @@ __tcsetattr (int fd, int optional_action
 | ||||
|  { | ||||
|    struct __kernel_termios k_termios; | ||||
|    unsigned long int cmd; | ||||
| +  int retval;
 | ||||
|   | ||||
|    switch (optional_actions) | ||||
|      { | ||||
| @@ -75,7 +76,36 @@ __tcsetattr (int fd, int optional_action
 | ||||
|    memcpy (&k_termios.c_cc[0], &termios_p->c_cc[0], | ||||
|  	  __KERNEL_NCCS * sizeof (cc_t)); | ||||
|   | ||||
| -  return INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
 | ||||
| +  retval = INLINE_SYSCALL (ioctl, 3, fd, cmd, &k_termios);
 | ||||
| +
 | ||||
| +  if (retval == 0 && cmd == TCSETS)
 | ||||
| +    {
 | ||||
| +      /* The Linux kernel has a bug which silently ignore the invalid
 | ||||
| +        c_cflag on pty. We have to check it here. */
 | ||||
| +      int save = errno;
 | ||||
| +      retval = INLINE_SYSCALL (ioctl, 3, fd, TCGETS, &k_termios);
 | ||||
| +      if (retval)
 | ||||
| +       {
 | ||||
| +         /* We cannot verify if the setting is ok. We don't return
 | ||||
| +            an error (?). */
 | ||||
| +         __set_errno (save);
 | ||||
| +         retval = 0;
 | ||||
| +       }
 | ||||
| +      else if ((termios_p->c_cflag & (PARENB | CREAD))
 | ||||
| +              != (k_termios.c_cflag & (PARENB | CREAD))
 | ||||
| +              || ((termios_p->c_cflag & CSIZE)
 | ||||
| +                  && ((termios_p->c_cflag & CSIZE)
 | ||||
| +                      != (k_termios.c_cflag & CSIZE))))
 | ||||
| +       {
 | ||||
| +         /* It looks like the Linux kernel silently changed the
 | ||||
| +            PARENB/CREAD/CSIZE bits in c_cflag. Report it as an
 | ||||
| +            error. */
 | ||||
| +         __set_errno (EINVAL);
 | ||||
| +         retval = -1;
 | ||||
| +       }
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  return retval;
 | ||||
|  } | ||||
|  weak_alias (__tcsetattr, tcsetattr) | ||||
|  libc_hidden_def (tcsetattr) | ||||
							
								
								
									
										49
									
								
								SOURCES/glibc-fedora-localedata-rh61908.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								SOURCES/glibc-fedora-localedata-rh61908.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | ||||
| Short description: Add 4 ISO-8859-15 locales to SUPPORTED for Euro symbol. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Bug-RHEL: #61908 | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| Very early RHL 7.3 requirement to add these locales so users can | ||||
| get access to Euro symbol. We should review this bug and decide if | ||||
| the UTF-8 locales are now serving the same purpose and drop the | ||||
| additional locales. | ||||
| 
 | ||||
| * Tue Mar 26 2002 Jakub Jelinek <jakub@redhat.com> 2.2.5-28 | ||||
| - add a couple of .ISO-8859-15 locales (#61908)
 | ||||
| 
 | ||||
| diff -Nrup a/localedata/SUPPORTED b/localedata/SUPPORTED
 | ||||
| --- a/localedata/SUPPORTED	2012-11-25 12:59:31.000000000 -0700
 | ||||
| +++ b/localedata/SUPPORTED	2012-11-26 12:58:43.298223018 -0700
 | ||||
| @@ -89,6 +89,7 @@ cy_GB.UTF-8/UTF-8 \
 | ||||
|  cy_GB/ISO-8859-14 \ | ||||
|  da_DK.UTF-8/UTF-8 \ | ||||
|  da_DK/ISO-8859-1 \ | ||||
| +da_DK.ISO-8859-15/ISO-8859-15 \
 | ||||
|  de_AT.UTF-8/UTF-8 \ | ||||
|  de_AT/ISO-8859-1 \ | ||||
|  de_AT@euro/ISO-8859-15 \ | ||||
| @@ -121,6 +122,7 @@ en_DK.UTF-8/UTF-8 \
 | ||||
|  en_DK/ISO-8859-1 \ | ||||
|  en_GB.UTF-8/UTF-8 \ | ||||
|  en_GB/ISO-8859-1 \ | ||||
| +en_GB.ISO-8859-15/ISO-8859-15 \
 | ||||
|  en_HK.UTF-8/UTF-8 \ | ||||
|  en_HK/ISO-8859-1 \ | ||||
|  en_IE.UTF-8/UTF-8 \ | ||||
| @@ -136,6 +138,7 @@ en_SG.UTF-8/UTF-8 \
 | ||||
|  en_SG/ISO-8859-1 \ | ||||
|  en_US.UTF-8/UTF-8 \ | ||||
|  en_US/ISO-8859-1 \ | ||||
| +en_US.ISO-8859-15/ISO-8859-15 \
 | ||||
|  en_ZA.UTF-8/UTF-8 \ | ||||
|  en_ZA/ISO-8859-1 \ | ||||
|  en_ZM/UTF-8 \ | ||||
| @@ -385,6 +388,7 @@ sv_FI/ISO-8859-1 \
 | ||||
|  sv_FI@euro/ISO-8859-15 \ | ||||
|  sv_SE.UTF-8/UTF-8 \ | ||||
|  sv_SE/ISO-8859-1 \ | ||||
| +sv_SE.ISO-8859-15/ISO-8859-15 \
 | ||||
|  sw_KE/UTF-8 \ | ||||
|  sw_TZ/UTF-8 \ | ||||
|  szl_PL/UTF-8 \ | ||||
							
								
								
									
										21
									
								
								SOURCES/glibc-fedora-localedef.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SOURCES/glibc-fedora-localedef.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| Short description: Fedora-specific glibc install locale changes. | ||||
| Author(s):  Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| The Fedora glibc build and install does not need the normal install | ||||
| behaviour which updates the locale archive. The Fedora install phase | ||||
| in the spec file of the rpm will handle this manually. | ||||
| 
 | ||||
| diff --git a/localedata/Makefile b/localedata/Makefile
 | ||||
| index a5f3c92d58954dfc..56719c7c714aa0f1 100644
 | ||||
| --- a/localedata/Makefile
 | ||||
| +++ b/localedata/Makefile
 | ||||
| @@ -218,6 +218,7 @@ $(INSTALL-SUPPORTED-LOCALES): install-locales-dir
 | ||||
|  	echo -n '...'; \ | ||||
|  	input=`echo $$locale | sed 's/\([^.]*\)[^@]*\(.*\)/\1\2/'`; \ | ||||
|  	$(LOCALEDEF) $$flags --alias-file=../intl/locale.alias \ | ||||
| +		     --no-archive \
 | ||||
|  		     -i locales/$$input -f charmaps/$$charset \ | ||||
|  		     $(addprefix --prefix=,$(install_root)) $$locale \ | ||||
|  	&& echo ' done'; \ | ||||
							
								
								
									
										46
									
								
								SOURCES/glibc-fedora-locarchive.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								SOURCES/glibc-fedora-locarchive.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| Short description: Allow access to internal locale archive functions. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| This is a part of commit glibc-2.3.3-1492-ga891c7b, | ||||
| needed for fedora/build-locale-archive.c only. | ||||
| 
 | ||||
| 2007-04-16  Jakub Jelinek  <jakub@redhat.com> | ||||
| 
 | ||||
| 	* locale/programs/locarchive.c (add_alias, insert_name): Remove static. | ||||
| 
 | ||||
| diff -Nrup a/locale/programs/locarchive.c b/locale/programs/locarchive.c
 | ||||
| --- a/locale/programs/locarchive.c	2012-06-05 07:42:49.000000000 -0600
 | ||||
| +++ b/locale/programs/locarchive.c	2012-06-07 12:15:21.585319540 -0600
 | ||||
| @@ -252,9 +252,9 @@ oldlocrecentcmp (const void *a, const vo
 | ||||
|  /* forward decls for below */ | ||||
|  static uint32_t add_locale (struct locarhandle *ah, const char *name, | ||||
|  			    locale_data_t data, bool replace); | ||||
| -static void add_alias (struct locarhandle *ah, const char *alias,
 | ||||
| -		       bool replace, const char *oldname,
 | ||||
| -		       uint32_t *locrec_offset_p);
 | ||||
| +void add_alias (struct locarhandle *ah, const char *alias,
 | ||||
| +		bool replace, const char *oldname,
 | ||||
| +		uint32_t *locrec_offset_p);
 | ||||
|   | ||||
|   | ||||
|  static bool | ||||
| @@ -635,7 +635,7 @@ close_archive (struct locarhandle *ah)
 | ||||
|  #include "../../intl/explodename.c" | ||||
|  #include "../../intl/l10nflist.c" | ||||
|   | ||||
| -static struct namehashent *
 | ||||
| +struct namehashent *
 | ||||
|  insert_name (struct locarhandle *ah, | ||||
|  	     const char *name, size_t name_len, bool replace) | ||||
|  { | ||||
| @@ -693,7 +693,7 @@ insert_name (struct locarhandle *ah,
 | ||||
|    return &namehashtab[idx]; | ||||
|  } | ||||
|   | ||||
| -static void
 | ||||
| +void
 | ||||
|  add_alias (struct locarhandle *ah, const char *alias, bool replace, | ||||
|  	   const char *oldname, uint32_t *locrec_offset_p) | ||||
|  { | ||||
							
								
								
									
										31
									
								
								SOURCES/glibc-fedora-manual-dircategory.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/glibc-fedora-manual-dircategory.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| Short description: Place glibc info into "Libraries" category. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| The category names for libraries is completely random including | ||||
| "Libraries", "GNU Libraries", "GNU libraries", and "Software libraries." | ||||
| In the GNU info manual the "Software libraries" category is given as an | ||||
| example, but really we need to standardize on a category for upstream. | ||||
| I suggest we drop this change after some upstream discussion. | ||||
| 
 | ||||
| From 4820b9175535e13df79ce816106016040014916e Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Jelinek <jakub@redhat.com> | ||||
| Date: Fri, 3 Nov 2006 16:31:21 +0000 | ||||
| Subject: [PATCH] Change @dircategory. | ||||
| 
 | ||||
| ---
 | ||||
|  manual/libc.texinfo |    2 +- | ||||
|  1 files changed, 1 insertions(+), 1 deletions(-) | ||||
| 
 | ||||
| --- a/manual/libc.texinfo
 | ||||
| +++ b/manual/libc.texinfo
 | ||||
| @@ -7,7 +7,7 @@
 | ||||
|  @include macros.texi | ||||
|   | ||||
|  @comment Tell install-info what to do. | ||||
| -@dircategory Software libraries
 | ||||
| +@dircategory Libraries
 | ||||
|  @direntry | ||||
|  * Libc: (libc).                 C library. | ||||
|  @end direntry | ||||
							
								
								
									
										31
									
								
								SOURCES/glibc-fedora-nis-rh188246.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/glibc-fedora-nis-rh188246.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| Short description: Fedora-specific enabling batch read in NSS. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Bug-RHEL: #188246 | ||||
| Upstream status: not-submitted | ||||
| 
 | ||||
| Enable batch read in NSS. It's not clear if this is always a win or | ||||
| just a win for NIS+, this needs to be analyzed and sent upstream or | ||||
| removed. | ||||
| 
 | ||||
| From baba5d9461d4e8a581ac26fe4412ad783ffc73e7 Mon Sep 17 00:00:00 2001 | ||||
| From: Jakub Jelinek <jakub@redhat.com> | ||||
| Date: Mon, 1 May 2006 08:02:53 +0000 | ||||
| Subject: [PATCH] Enable SETENT_BATCH_READ nis/nss option by default | ||||
| 
 | ||||
| * Mon May  1 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-4 | ||||
| - SETENT_BATCH_READ /etc/default/nss option for speeding up
 | ||||
|   some usages of NIS+ (#188246) | ||||
| 
 | ||||
| diff --git a/nis/nss b/nis/nss
 | ||||
| --- a/nis/nss
 | ||||
| +++ b/nis/nss
 | ||||
| @@ -25,7 +25,7 @@
 | ||||
|  #  memory with every getXXent() call.  Otherwise each getXXent() call | ||||
|  #  might result into a network communication with the server to get | ||||
|  #  the next entry. | ||||
| -#SETENT_BATCH_READ=TRUE
 | ||||
| +SETENT_BATCH_READ=TRUE
 | ||||
|  # | ||||
|  # ADJUNCT_AS_SHADOW | ||||
|  #  If set to TRUE, the passwd routines in the NIS NSS module will not | ||||
							
								
								
									
										20
									
								
								SOURCES/glibc-fedora-nscd.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								SOURCES/glibc-fedora-nscd.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| Short description: NSCD must use nscd user. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| Fedora-specific configuration adjustment to introduce the nscd user. | ||||
| (Upstream does not assume this user exists.) | ||||
| 
 | ||||
| diff -Nrup a/nscd/nscd.conf b/nscd/nscd.conf
 | ||||
| --- a/nscd/nscd.conf	2012-06-05 07:42:49.000000000 -0600
 | ||||
| +++ b/nscd/nscd.conf	2012-06-07 12:15:21.818318670 -0600
 | ||||
| @@ -33,7 +33,7 @@
 | ||||
|  #	logfile			/var/log/nscd.log | ||||
|  #	threads			4 | ||||
|  #	max-threads		32 | ||||
| -#	server-user		nobody
 | ||||
| +	server-user		nscd
 | ||||
|  #	stat-user		somebody | ||||
|  	debug-level		0 | ||||
|  #	reload-count		5 | ||||
							
								
								
									
										38
									
								
								SOURCES/glibc-fedora-streams-rh436349.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								SOURCES/glibc-fedora-streams-rh436349.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| Short description: Do not define _XOPEN_STREAMS. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Bug-Fedora: #436349 | ||||
| Upstream status: not-submitted | ||||
| 
 | ||||
| This patch should go upstream. Not defining _XOPEN_STREAMS is the | ||||
| same as setting it to -1 for POSIX conformance. The headers setting | ||||
| needs to be reviewed indepedently. | ||||
| 
 | ||||
| This is part of commit glibc-2.3.3-1564-gd0b6ac6 | ||||
| 
 | ||||
| * Fri Mar 14 2008 Jakub Jelinek <jakub@redhat.com> 2.7.90-11 | ||||
| - remove <stropts.h>, define _XOPEN_STREAMS -1 (#436349)
 | ||||
| 
 | ||||
| diff -Nrup a/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h b/nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
 | ||||
| --- a/sysdeps/unix/sysv/linux/bits/posix_opt.h	2012-06-05 07:42:49.000000000 -0600
 | ||||
| +++ b/sysdeps/unix/sysv/linux/bits/posix_opt.h	2012-06-07 12:15:21.817318674 -0600
 | ||||
| @@ -188,4 +188,7 @@
 | ||||
|  /* Typed memory objects are not available.  */ | ||||
|  #define _POSIX_TYPED_MEMORY_OBJECTS	-1 | ||||
|   | ||||
| +/* Streams are not available.  */
 | ||||
| +#define _XOPEN_STREAMS	-1
 | ||||
| +
 | ||||
|  #endif /* bits/posix_opt.h */ | ||||
| diff -Nrup a/streams/Makefile b/streams/Makefile
 | ||||
| --- a/streams/Makefile	2012-06-05 07:42:49.000000000 -0600
 | ||||
| +++ b/streams/Makefile	2012-06-07 12:15:21.824318649 -0600
 | ||||
| @@ -20,7 +20,7 @@
 | ||||
|   | ||||
|  include ../Makeconfig | ||||
|   | ||||
| -headers		= stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
 | ||||
| +#headers		= stropts.h sys/stropts.h bits/stropts.h bits/xtitypes.h
 | ||||
|  routines	= isastream getmsg getpmsg putmsg putpmsg fattach fdetach | ||||
|   | ||||
|  include ../Rules | ||||
							
								
								
									
										21
									
								
								SOURCES/glibc-nscd-sysconfig.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								SOURCES/glibc-nscd-sysconfig.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | ||||
| Short description: Provide options to nscd startup. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| Fedora-specific nscd startup configuration file. | ||||
| 
 | ||||
| diff --git a/nscd/nscd.service b/nscd/nscd.service
 | ||||
| index b7428a3..19ba185 100644
 | ||||
| --- a/nscd/nscd.service
 | ||||
| +++ b/nscd/nscd.service
 | ||||
| @@ -5,7 +5,8 @@ Description=Name Service Cache Daemon
 | ||||
|   | ||||
|  [Service] | ||||
|  Type=forking | ||||
| -ExecStart=/usr/sbin/nscd
 | ||||
| +EnvironmentFile=-/etc/sysconfig/nscd
 | ||||
| +ExecStart=/usr/sbin/nscd $NSCD_OPTIONS
 | ||||
|  ExecStop=/usr/sbin/nscd --shutdown | ||||
|  ExecReload=/usr/sbin/nscd -i passwd | ||||
|  ExecReload=/usr/sbin/nscd -i group | ||||
							
								
								
									
										40
									
								
								SOURCES/glibc-python3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								SOURCES/glibc-python3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,40 @@ | ||||
| Use python3 for installed executable python scripts. | ||||
| 
 | ||||
| Fedora is a Python3-only distribution: | ||||
| https://fedoraproject.org/wiki/FinalizingFedoraSwitchtoPython3 | ||||
| 
 | ||||
| This fixes build failures where builders may strictly enforce only | ||||
| python3 during a transitional phase. | ||||
| 
 | ||||
| Author: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| diff --git a/benchtests/scripts/compare_bench.py b/benchtests/scripts/compare_bench.py
 | ||||
| index ea25f778c09bba9d..b53beb3c6e32c3cf 100755
 | ||||
| --- a/benchtests/scripts/compare_bench.py
 | ||||
| +++ b/benchtests/scripts/compare_bench.py
 | ||||
| @@ -1,4 +1,4 @@
 | ||||
| -#!/usr/bin/python
 | ||||
| +#!/usr/bin/python3
 | ||||
|  # Copyright (C) 2015-2018 Free Software Foundation, Inc. | ||||
|  # This file is part of the GNU C Library. | ||||
|  # | ||||
| diff --git a/benchtests/scripts/import_bench.py b/benchtests/scripts/import_bench.py
 | ||||
| index 602b3f954d4801a6..76bf1528a5418748 100644
 | ||||
| --- a/benchtests/scripts/import_bench.py
 | ||||
| +++ b/benchtests/scripts/import_bench.py
 | ||||
| @@ -1,4 +1,4 @@
 | ||||
| -#!/usr/bin/python
 | ||||
| +#!/usr/bin/python3
 | ||||
|  # Copyright (C) 2015-2018 Free Software Foundation, Inc. | ||||
|  # This file is part of the GNU C Library. | ||||
|  # | ||||
| diff --git a/benchtests/scripts/validate_benchout.py b/benchtests/scripts/validate_benchout.py
 | ||||
| index 6147f05bec3a4844..9a5c7947ee4ed7e9 100755
 | ||||
| --- a/benchtests/scripts/validate_benchout.py
 | ||||
| +++ b/benchtests/scripts/validate_benchout.py
 | ||||
| @@ -1,4 +1,4 @@
 | ||||
| -#!/usr/bin/python
 | ||||
| +#!/usr/bin/python3
 | ||||
|  # Copyright (C) 2014-2018 Free Software Foundation, Inc. | ||||
|  # This file is part of the GNU C Library. | ||||
|  # | ||||
							
								
								
									
										38
									
								
								SOURCES/glibc-rh1070416.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								SOURCES/glibc-rh1070416.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| Short description: Add syslog.target dependency. | ||||
| Author(s): Fedora glibc team <glibc@lists.fedoraproject.org> | ||||
| Origin: PATCH | ||||
| Bug-Fedora: #1070416 | ||||
| Upstream status: not-needed | ||||
| 
 | ||||
| Fedora-specific changes to the nscd.service file. | ||||
| See also: glibc-nscd-sysconfig.patch. | ||||
| 
 | ||||
| --- a/nscd/nscd.service
 | ||||
| +++ b/nscd/nscd.service
 | ||||
| @@ -2,6 +2,7 @@
 | ||||
|   | ||||
|  [Unit] | ||||
|  Description=Name Service Cache Daemon | ||||
| +After=syslog.target
 | ||||
|   | ||||
|  [Service] | ||||
|  Type=forking | ||||
| @@ -17,3 +18,4 @@
 | ||||
|   | ||||
|  [Install] | ||||
|  WantedBy=multi-user.target | ||||
| +Also=nscd.socket
 | ||||
| diff --git a/nscd/nscd.socket b/nscd/nscd.socket
 | ||||
| new file mode 100644 | ||||
| index 0000000..7e512d5
 | ||||
| --- /dev/null
 | ||||
| +++ b/nscd/nscd.socket
 | ||||
| @@ -0,0 +1,8 @@
 | ||||
| +[Unit]
 | ||||
| +Description=Name Service Cache Daemon Socket
 | ||||
| +
 | ||||
| +[Socket]
 | ||||
| +ListenDatagram=/var/run/nscd/socket
 | ||||
| +
 | ||||
| +[Install]
 | ||||
| +WantedBy=sockets.target
 | ||||
							
								
								
									
										22
									
								
								SOURCES/glibc-rh1577365.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								SOURCES/glibc-rh1577365.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| Please see the following bug for a complete summary: | ||||
| https://bugzilla.redhat.com/show_bug.cgi?id=1615608 | ||||
| 
 | ||||
| Index: glibc-2.28/manual/startup.texi
 | ||||
| ===================================================================
 | ||||
| --- glibc-2.28.orig/manual/startup.texi
 | ||||
| +++ glibc-2.28/manual/startup.texi
 | ||||
| @@ -1005,14 +1005,6 @@ This function actually terminates the pr
 | ||||
|  intercept this signal; see @ref{Signal Handling}. | ||||
|  @end deftypefun | ||||
|   | ||||
| -@c Put in by rms.  Don't remove.
 | ||||
| -@cartouche
 | ||||
| -@strong{Future Change Warning:} Proposed Federal censorship regulations
 | ||||
| -may prohibit us from giving you information about the possibility of
 | ||||
| -calling this function.  We would be required to say that this is not an
 | ||||
| -acceptable way of terminating a program.
 | ||||
| -@end cartouche
 | ||||
| -
 | ||||
|  @node Termination Internals | ||||
|  @subsection Termination Internals | ||||
|   | ||||
							
								
								
									
										24
									
								
								SOURCES/glibc-rh1577438.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								SOURCES/glibc-rh1577438.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| Patch by Hanataka Shinya <hanataka.shinya@gmail.com> from | ||||
| <https://sourceware.org/bugzilla/show_bug.cgi?id=24405>.  Confirmed by TAMUKI | ||||
| Shoichi's patch in | ||||
| <https://sourceware.org/ml/libc-alpha/2019-04/msg00005.html>. | ||||
| 
 | ||||
| The official announcement by the Japanese Prime Minister in | ||||
| <https://www.kantei.go.jp/jp/tyoukanpress/201904/1_a.html> uses U+4EE4 U+548C | ||||
| as well. | ||||
| 
 | ||||
| diff --git a/localedata/locales/ja_JP b/localedata/locales/ja_JP
 | ||||
| index 1fd2fee44b2879d9..30190b624856cc53 100644
 | ||||
| --- a/localedata/locales/ja_JP
 | ||||
| +++ b/localedata/locales/ja_JP
 | ||||
| @@ -14946,7 +14946,9 @@ am_pm	"<U5348><U524D>";"<U5348><U5F8C>"
 | ||||
|   | ||||
|  t_fmt_ampm "%p%I<U6642>%M<U5206>%S<U79D2>" | ||||
|   | ||||
| -era	"+:2:1990//01//01:+*:<U5E73><U6210>:%EC%Ey<U5E74>";/
 | ||||
| +era	"+:2:2020//01//01:+*:<U4EE4><U548C>:%EC%Ey<U5E74>";/
 | ||||
| +	"+:1:2019//05//01:2019//12//31:<U4EE4><U548C>:%EC<U5143><U5E74>";/
 | ||||
| +	"+:2:1990//01//01:2019//04//30:<U5E73><U6210>:%EC%Ey<U5E74>";/
 | ||||
|  	"+:1:1989//01//08:1989//12//31:<U5E73><U6210>:%EC<U5143><U5E74>";/ | ||||
|  	"+:2:1927//01//01:1989//01//07:<U662D><U548C>:%EC%Ey<U5E74>";/ | ||||
|  	"+:1:1926//12//25:1926//12//31:<U662D><U548C>:%EC<U5143><U5E74>";/ | ||||
							
								
								
									
										254
									
								
								SOURCES/glibc-rh1614253.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										254
									
								
								SOURCES/glibc-rh1614253.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,254 @@ | ||||
| commit 4b25485f03158959cff45379eecc1d73c7dcdd11 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Fri Aug 10 11:19:26 2018 +0200 | ||||
| 
 | ||||
|     Linux: Rewrite __old_getdents64 [BZ #23497] | ||||
|      | ||||
|     Commit 298d0e3129c0b5137f4989275b13fe30d0733c4d ("Consolidate Linux | ||||
|     getdents{64} implementation") broke the implementation because it does | ||||
|     not take into account struct offset differences. | ||||
|      | ||||
|     The new implementation is close to the old one, before the | ||||
|     consolidation, but has been cleaned up slightly. | ||||
|      | ||||
|     (cherry picked from commit 690652882b499defb3d950dfeff8fe421d13cab5) | ||||
| 
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
 | ||||
| index f71cc39c7e257a0a..773aaea0e980bdd6 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/Makefile
 | ||||
| +++ b/sysdeps/unix/sysv/linux/Makefile
 | ||||
| @@ -161,6 +161,7 @@ inhibit-glue = yes
 | ||||
|   | ||||
|  ifeq ($(subdir),dirent) | ||||
|  sysdep_routines += getdirentries getdirentries64 | ||||
| +tests-internal += tst-readdir64-compat
 | ||||
|  endif | ||||
|   | ||||
|  ifeq ($(subdir),nis) | ||||
| diff --git a/sysdeps/unix/sysv/linux/getdents64.c b/sysdeps/unix/sysv/linux/getdents64.c
 | ||||
| index 3bde0cf4f0226f95..bc140b5a7fac3040 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/getdents64.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/getdents64.c
 | ||||
| @@ -33,41 +33,80 @@ strong_alias (__getdents64, __getdents)
 | ||||
|  # include <shlib-compat.h> | ||||
|   | ||||
|  # if SHLIB_COMPAT(libc, GLIBC_2_1, GLIBC_2_2) | ||||
| -# include <olddirent.h>
 | ||||
| +#  include <olddirent.h>
 | ||||
| +#  include <unistd.h>
 | ||||
|   | ||||
| -/* kernel definition of as of 3.2.  */
 | ||||
| -struct compat_linux_dirent
 | ||||
| +static ssize_t
 | ||||
| +handle_overflow (int fd, __off64_t offset, ssize_t count)
 | ||||
|  { | ||||
| -  /* Both d_ino and d_off are compat_ulong_t which are defined in all
 | ||||
| -     architectures as 'u32'.  */
 | ||||
| -  uint32_t        d_ino;
 | ||||
| -  uint32_t        d_off;
 | ||||
| -  unsigned short  d_reclen;
 | ||||
| -  char            d_name[1];
 | ||||
| -};
 | ||||
| +  /* If this is the first entry in the buffer, we can report the
 | ||||
| +     error.  */
 | ||||
| +  if (count == 0)
 | ||||
| +    {
 | ||||
| +      __set_errno (EOVERFLOW);
 | ||||
| +      return -1;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  /* Otherwise, seek to the overflowing entry, so that the next call
 | ||||
| +     will report the error, and return the data read so far..  */
 | ||||
| +  if (__lseek64 (fd, offset, SEEK_SET) != 0)
 | ||||
| +    return -1;
 | ||||
| +  return count;
 | ||||
| +}
 | ||||
|   | ||||
|  ssize_t | ||||
|  __old_getdents64 (int fd, char *buf, size_t nbytes) | ||||
|  { | ||||
| -  ssize_t retval = INLINE_SYSCALL_CALL (getdents, fd, buf, nbytes);
 | ||||
| +  /* We do not move the individual directory entries.  This is only
 | ||||
| +     possible if the target type (struct __old_dirent64) is smaller
 | ||||
| +     than the source type.  */
 | ||||
| +  _Static_assert (offsetof (struct __old_dirent64, d_name)
 | ||||
| +		  <= offsetof (struct dirent64, d_name),
 | ||||
| +		  "__old_dirent64 is larger than dirent64");
 | ||||
| +  _Static_assert (__alignof__ (struct __old_dirent64)
 | ||||
| +		  <= __alignof__ (struct dirent64),
 | ||||
| +		  "alignment of __old_dirent64 is larger than dirent64");
 | ||||
|   | ||||
| -  /* The kernel added the d_type value after the name.  Change this now.  */
 | ||||
| -  if (retval != -1)
 | ||||
| +  ssize_t retval = INLINE_SYSCALL_CALL (getdents64, fd, buf, nbytes);
 | ||||
| +  if (retval > 0)
 | ||||
|      { | ||||
| -      union
 | ||||
| -      {
 | ||||
| -	struct compat_linux_dirent k;
 | ||||
| -	struct dirent u;
 | ||||
| -      } *kbuf = (void *) buf;
 | ||||
| -
 | ||||
| -      while ((char *) kbuf < buf + retval)
 | ||||
| +      char *p = buf;
 | ||||
| +      char *end = buf + retval;
 | ||||
| +      while (p < end)
 | ||||
|  	{ | ||||
| -	  char d_type = *((char *) kbuf + kbuf->k.d_reclen - 1);
 | ||||
| -	  memmove (kbuf->u.d_name, kbuf->k.d_name,
 | ||||
| -		   strlen (kbuf->k.d_name) + 1);
 | ||||
| -	  kbuf->u.d_type = d_type;
 | ||||
| +	  struct dirent64 *source = (struct dirent64 *) p;
 | ||||
| +
 | ||||
| +	  /* Copy out the fixed-size data.  */
 | ||||
| +	  __ino_t ino = source->d_ino;
 | ||||
| +	  __off64_t offset = source->d_off;
 | ||||
| +	  unsigned int reclen = source->d_reclen;
 | ||||
| +	  unsigned char type = source->d_type;
 | ||||
| +
 | ||||
| +	  /* Check for ino_t overflow.  */
 | ||||
| +	  if (__glibc_unlikely (ino != source->d_ino))
 | ||||
| +	    return handle_overflow (fd, offset, p - buf);
 | ||||
| +
 | ||||
| +	  /* Convert to the target layout.  Use a separate struct and
 | ||||
| +	     memcpy to side-step aliasing issues.  */
 | ||||
| +	  struct __old_dirent64 result;
 | ||||
| +	  result.d_ino = ino;
 | ||||
| +	  result.d_off = offset;
 | ||||
| +	  result.d_reclen = reclen;
 | ||||
| +	  result.d_type = type;
 | ||||
| +
 | ||||
| +	  /* Write the fixed-sized part of the result to the
 | ||||
| +	     buffer.  */
 | ||||
| +	  size_t result_name_offset = offsetof (struct __old_dirent64, d_name);
 | ||||
| +	  memcpy (p, &result, result_name_offset);
 | ||||
| +
 | ||||
| +	  /* Adjust the position of the name if necessary.  Copy
 | ||||
| +	     everything until the end of the record, including the
 | ||||
| +	     terminating NUL byte.  */
 | ||||
| +	  if (result_name_offset != offsetof (struct dirent64, d_name))
 | ||||
| +	    memmove (p + result_name_offset, source->d_name,
 | ||||
| +		     reclen - offsetof (struct dirent64, d_name));
 | ||||
|   | ||||
| -	  kbuf = (void *) ((char *) kbuf + kbuf->k.d_reclen);
 | ||||
| +	  p += reclen;
 | ||||
|  	} | ||||
|       } | ||||
|    return retval; | ||||
| diff --git a/sysdeps/unix/sysv/linux/tst-readdir64-compat.c b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..43c4a8477c7403c5
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/unix/sysv/linux/tst-readdir64-compat.c
 | ||||
| @@ -0,0 +1,111 @@
 | ||||
| +/* Test readdir64 compatibility symbol.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <dirent.h>
 | ||||
| +#include <dlfcn.h>
 | ||||
| +#include <errno.h>
 | ||||
| +#include <shlib-compat.h>
 | ||||
| +#include <stdbool.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +
 | ||||
| +/* Copied from <olddirent.h>.  */
 | ||||
| +struct __old_dirent64
 | ||||
| +  {
 | ||||
| +    __ino_t d_ino;
 | ||||
| +    __off64_t d_off;
 | ||||
| +    unsigned short int d_reclen;
 | ||||
| +    unsigned char d_type;
 | ||||
| +    char d_name[256];
 | ||||
| +  };
 | ||||
| +
 | ||||
| +typedef struct __old_dirent64 *(*compat_readdir64_type) (DIR *);
 | ||||
| +
 | ||||
| +#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
 | ||||
| +struct __old_dirent64 *compat_readdir64 (DIR *);
 | ||||
| +compat_symbol_reference (libc, compat_readdir64, readdir64, GLIBC_2_1);
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +#if TEST_COMPAT (libc, GLIBC_2_1, GLIBC_2_2)
 | ||||
| +
 | ||||
| +  /* Directory stream using the non-compat readdir64 symbol.  The test
 | ||||
| +     checks against this.  */
 | ||||
| +  DIR *dir_reference = opendir (".");
 | ||||
| +  TEST_VERIFY_EXIT (dir_reference != NULL);
 | ||||
| +  DIR *dir_test = opendir (".");
 | ||||
| +  TEST_VERIFY_EXIT (dir_test != NULL);
 | ||||
| +
 | ||||
| +  /* This loop assumes that the enumeration order is consistent for
 | ||||
| +     two different handles.  Nothing should write to the current
 | ||||
| +     directory (in the source tree) while this test runs, so there
 | ||||
| +     should not be any difference due to races.  */
 | ||||
| +  size_t count = 0;
 | ||||
| +  while (true)
 | ||||
| +    {
 | ||||
| +      errno = 0;
 | ||||
| +      struct dirent64 *entry_reference = readdir64 (dir_reference);
 | ||||
| +      if (entry_reference == NULL && errno != 0)
 | ||||
| +        FAIL_EXIT1 ("readdir64 entry %zu: %m\n", count);
 | ||||
| +      struct __old_dirent64 *entry_test = compat_readdir64 (dir_test);
 | ||||
| +      if (entry_reference == NULL)
 | ||||
| +        {
 | ||||
| +          if (errno == EOVERFLOW)
 | ||||
| +            {
 | ||||
| +              TEST_VERIFY (entry_reference->d_ino
 | ||||
| +                           != (__ino_t) entry_reference->d_ino);
 | ||||
| +              printf ("info: inode number overflow at entry %zu\n", count);
 | ||||
| +              break;
 | ||||
| +            }
 | ||||
| +          if (errno != 0)
 | ||||
| +            FAIL_EXIT1 ("compat readdir64 entry %zu: %m\n", count);
 | ||||
| +        }
 | ||||
| +
 | ||||
| +      /* Check that both streams end at the same time.  */
 | ||||
| +      if (entry_reference == NULL)
 | ||||
| +        {
 | ||||
| +          TEST_VERIFY (entry_test == NULL);
 | ||||
| +          break;
 | ||||
| +        }
 | ||||
| +      else
 | ||||
| +        TEST_VERIFY_EXIT (entry_test != NULL);
 | ||||
| +
 | ||||
| +      /* Check that the entries are the same.  */
 | ||||
| +      TEST_COMPARE_BLOB (entry_reference->d_name,
 | ||||
| +                         strlen (entry_reference->d_name),
 | ||||
| +                         entry_test->d_name, strlen (entry_test->d_name));
 | ||||
| +      TEST_COMPARE (entry_reference->d_ino, entry_test->d_ino);
 | ||||
| +      TEST_COMPARE (entry_reference->d_off, entry_test->d_off);
 | ||||
| +      TEST_COMPARE (entry_reference->d_type, entry_test->d_type);
 | ||||
| +      TEST_COMPARE (entry_reference->d_reclen, entry_test->d_reclen);
 | ||||
| +
 | ||||
| +      ++count;
 | ||||
| +    }
 | ||||
| +  printf ("info: %zu directory entries found\n", count);
 | ||||
| +  TEST_VERIFY (count >= 3);     /* ".", "..", and some source files.  */
 | ||||
| +
 | ||||
| +  TEST_COMPARE (closedir (dir_test), 0);
 | ||||
| +  TEST_COMPARE (closedir (dir_reference), 0);
 | ||||
| +#endif
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										154
									
								
								SOURCES/glibc-rh1614979.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										154
									
								
								SOURCES/glibc-rh1614979.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,154 @@ | ||||
| commit d524fa6c35e675eedbd8fe6cdf4db0b49c658026 | ||||
| Author: H.J. Lu <hjl.tools@gmail.com> | ||||
| Date:   Thu Nov 8 10:06:58 2018 -0800 | ||||
| 
 | ||||
|     Check multiple NT_GNU_PROPERTY_TYPE_0 notes [BZ #23509] | ||||
|      | ||||
|     Linkers group input note sections with the same name into one output | ||||
|     note section with the same name.  One output note section is placed in | ||||
|     one PT_NOTE segment.  Since new linkers merge input .note.gnu.property | ||||
|     sections into one output .note.gnu.property section, there is only | ||||
|     one NT_GNU_PROPERTY_TYPE_0 note in one PT_NOTE segment with new linkers. | ||||
|     Since older linkers treat input .note.gnu.property section as a generic | ||||
|     note section and just concatenate all input .note.gnu.property sections | ||||
|     into one output .note.gnu.property section without merging them, we may | ||||
|     see multiple NT_GNU_PROPERTY_TYPE_0 notes in one PT_NOTE segment with | ||||
|     older linkers. | ||||
|      | ||||
|     When an older linker is used to created the program on CET-enabled OS, | ||||
|     the linker output has a single .note.gnu.property section with multiple | ||||
|     NT_GNU_PROPERTY_TYPE_0 notes, some of which have IBT and SHSTK enable | ||||
|     bits set even if the program isn't CET enabled.  Such programs will | ||||
|     crash on CET-enabled machines.  This patch updates the note parser: | ||||
|      | ||||
|     1. Skip note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed. | ||||
|     2. Check multiple NT_GNU_PROPERTY_TYPE_0 notes. | ||||
|      | ||||
|             [BZ #23509] | ||||
|             * sysdeps/x86/dl-prop.h (_dl_process_cet_property_note): Skip | ||||
|             note parsing if a NT_GNU_PROPERTY_TYPE_0 note has been processed. | ||||
|             Update the l_cet field when processing NT_GNU_PROPERTY_TYPE_0 note. | ||||
|             Check multiple NT_GNU_PROPERTY_TYPE_0 notes. | ||||
|             * sysdeps/x86/link_map.h (l_cet): Expand to 3 bits,  Add | ||||
|             lc_unknown. | ||||
| 
 | ||||
| diff --git a/sysdeps/x86/dl-prop.h b/sysdeps/x86/dl-prop.h
 | ||||
| index 26c3131ac5e2d080..9ab890d12bb99133 100644
 | ||||
| --- a/sysdeps/x86/dl-prop.h
 | ||||
| +++ b/sysdeps/x86/dl-prop.h
 | ||||
| @@ -49,6 +49,10 @@ _dl_process_cet_property_note (struct link_map *l,
 | ||||
|  			      const ElfW(Addr) align) | ||||
|  { | ||||
|  #if CET_ENABLED | ||||
| +  /* Skip if we have seen a NT_GNU_PROPERTY_TYPE_0 note before.  */
 | ||||
| +  if (l->l_cet != lc_unknown)
 | ||||
| +    return;
 | ||||
| +
 | ||||
|    /* The NT_GNU_PROPERTY_TYPE_0 note must be aliged to 4 bytes in | ||||
|       32-bit objects and to 8 bytes in 64-bit objects.  Skip notes | ||||
|       with incorrect alignment.  */ | ||||
| @@ -57,6 +61,9 @@ _dl_process_cet_property_note (struct link_map *l,
 | ||||
|   | ||||
|    const ElfW(Addr) start = (ElfW(Addr)) note; | ||||
|   | ||||
| +  unsigned int feature_1 = 0;
 | ||||
| +  unsigned int last_type = 0;
 | ||||
| +
 | ||||
|    while ((ElfW(Addr)) (note + 1) - start < size) | ||||
|      { | ||||
|        /* Find the NT_GNU_PROPERTY_TYPE_0 note.  */ | ||||
| @@ -64,10 +71,18 @@ _dl_process_cet_property_note (struct link_map *l,
 | ||||
|  	  && note->n_type == NT_GNU_PROPERTY_TYPE_0 | ||||
|  	  && memcmp (note + 1, "GNU", 4) == 0) | ||||
|  	{ | ||||
| +	  /* Stop if we see more than one GNU property note which may
 | ||||
| +	     be generated by the older linker.  */
 | ||||
| +	  if (l->l_cet != lc_unknown)
 | ||||
| +	    return;
 | ||||
| +
 | ||||
| +	  /* Check CET status now.  */
 | ||||
| +	  l->l_cet = lc_none;
 | ||||
| +
 | ||||
|  	  /* Check for invalid property.  */ | ||||
|  	  if (note->n_descsz < 8 | ||||
|  	      || (note->n_descsz % sizeof (ElfW(Addr))) != 0) | ||||
| -	    break;
 | ||||
| +	    return;
 | ||||
|   | ||||
|  	  /* Start and end of property array.  */ | ||||
|  	  unsigned char *ptr = (unsigned char *) (note + 1) + 4; | ||||
| @@ -78,9 +93,15 @@ _dl_process_cet_property_note (struct link_map *l,
 | ||||
|  	      unsigned int type = *(unsigned int *) ptr; | ||||
|  	      unsigned int datasz = *(unsigned int *) (ptr + 4); | ||||
|   | ||||
| +	      /* Property type must be in ascending order.  */
 | ||||
| +	      if (type < last_type)
 | ||||
| +		return;
 | ||||
| +
 | ||||
|  	      ptr += 8; | ||||
|  	      if ((ptr + datasz) > ptr_end) | ||||
| -		break;
 | ||||
| +		return;
 | ||||
| +
 | ||||
| +	      last_type = type;
 | ||||
|   | ||||
|  	      if (type == GNU_PROPERTY_X86_FEATURE_1_AND) | ||||
|  		{ | ||||
| @@ -89,14 +110,18 @@ _dl_process_cet_property_note (struct link_map *l,
 | ||||
|  		     we stop the search regardless if its size is correct | ||||
|  		     or not.  There is no point to continue if this note | ||||
|  		     is ill-formed.  */ | ||||
| -		  if (datasz == 4)
 | ||||
| -		    {
 | ||||
| -		      unsigned int feature_1 = *(unsigned int *) ptr;
 | ||||
| -		      if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
 | ||||
| -			l->l_cet |= lc_ibt;
 | ||||
| -		      if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
 | ||||
| -			l->l_cet |= lc_shstk;
 | ||||
| -		    }
 | ||||
| +		  if (datasz != 4)
 | ||||
| +		    return;
 | ||||
| +
 | ||||
| +		  feature_1 = *(unsigned int *) ptr;
 | ||||
| +
 | ||||
| +		  /* Keep searching for the next GNU property note
 | ||||
| +		     generated by the older linker.  */
 | ||||
| +		  break;
 | ||||
| +		}
 | ||||
| +	      else if (type > GNU_PROPERTY_X86_FEATURE_1_AND)
 | ||||
| +		{
 | ||||
| +		  /* Stop since property type is in ascending order.  */
 | ||||
|  		  return; | ||||
|  		} | ||||
|   | ||||
| @@ -112,6 +137,12 @@ _dl_process_cet_property_note (struct link_map *l,
 | ||||
|  	      + ELF_NOTE_NEXT_OFFSET (note->n_namesz, note->n_descsz, | ||||
|  				      align)); | ||||
|      } | ||||
| +
 | ||||
| +  /* We get here only if there is one or no GNU property note.  */
 | ||||
| +  if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_IBT))
 | ||||
| +    l->l_cet |= lc_ibt;
 | ||||
| +  if ((feature_1 & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
 | ||||
| +    l->l_cet |= lc_shstk;
 | ||||
|  #endif | ||||
|  } | ||||
|   | ||||
| diff --git a/sysdeps/x86/link_map.h b/sysdeps/x86/link_map.h
 | ||||
| index ef1206a9d2396a6f..9367ed08896794a4 100644
 | ||||
| --- a/sysdeps/x86/link_map.h
 | ||||
| +++ b/sysdeps/x86/link_map.h
 | ||||
| @@ -19,8 +19,9 @@
 | ||||
|  /* If this object is enabled with CET.  */ | ||||
|  enum | ||||
|    { | ||||
| -    lc_none = 0,			 /* Not enabled with CET.  */
 | ||||
| -    lc_ibt = 1 << 0,			 /* Enabled with IBT.  */
 | ||||
| -    lc_shstk = 1 << 1,			 /* Enabled with STSHK.  */
 | ||||
| +    lc_unknown = 0,			 /* Unknown CET status.  */
 | ||||
| +    lc_none = 1 << 0,			 /* Not enabled with CET.  */
 | ||||
| +    lc_ibt = 1 << 1,			 /* Enabled with IBT.  */
 | ||||
| +    lc_shstk = 1 << 2,			 /* Enabled with STSHK.  */
 | ||||
|      lc_ibt_and_shstk = lc_ibt | lc_shstk /* Enabled with both.  */ | ||||
| -  } l_cet:2;
 | ||||
| +  } l_cet:3;
 | ||||
							
								
								
									
										28
									
								
								SOURCES/glibc-rh1615781.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								SOURCES/glibc-rh1615781.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,28 @@ | ||||
| commit d05b05d1570ba3ae354a2f5a3cfeefb373b09979 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Aug 13 14:28:07 2018 +0200 | ||||
| 
 | ||||
|     error, error_at_line: Add missing va_end calls | ||||
|      | ||||
|     (cherry picked from commit b7b52b9dec337a08a89bc67638773be652eba332) | ||||
| 
 | ||||
| diff --git a/misc/error.c b/misc/error.c
 | ||||
| index b4e8b6c93886b737..03378e2f2aa6251e 100644
 | ||||
| --- a/misc/error.c
 | ||||
| +++ b/misc/error.c
 | ||||
| @@ -319,6 +319,7 @@ error (int status, int errnum, const char *message, ...)
 | ||||
|   | ||||
|    va_start (args, message); | ||||
|    error_tail (status, errnum, message, args); | ||||
| +  va_end (args);
 | ||||
|   | ||||
|  #ifdef _LIBC | ||||
|    _IO_funlockfile (stderr); | ||||
| @@ -390,6 +391,7 @@ error_at_line (int status, int errnum, const char *file_name,
 | ||||
|   | ||||
|    va_start (args, message); | ||||
|    error_tail (status, errnum, message, args); | ||||
| +  va_end (args);
 | ||||
|   | ||||
|  #ifdef _LIBC | ||||
|    _IO_funlockfile (stderr); | ||||
							
								
								
									
										35
									
								
								SOURCES/glibc-rh1615784.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								SOURCES/glibc-rh1615784.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| commit bfcfa22589f2b4277a65e60c6b736b6bbfbd87d0 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Aug 14 10:51:07 2018 +0200 | ||||
| 
 | ||||
|     nscd: Deallocate existing user names in file parser | ||||
|      | ||||
|     This avoids a theoretical memory leak (theoretical because it depends on | ||||
|     multiple server-user/stat-user directives in the configuration file). | ||||
|      | ||||
|     (cherry picked from commit 2d7acfac3ebf266dcbc82d0d6cc576f626953a03) | ||||
| 
 | ||||
| diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c
 | ||||
| index 265a02434dd26c29..7293b795b6bcf71e 100644
 | ||||
| --- a/nscd/nscd_conf.c
 | ||||
| +++ b/nscd/nscd_conf.c
 | ||||
| @@ -190,7 +190,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 | ||||
|  	  if (!arg1) | ||||
|  	    error (0, 0, _("Must specify user name for server-user option")); | ||||
|  	  else | ||||
| -	    server_user = xstrdup (arg1);
 | ||||
| +	    {
 | ||||
| +	      free ((char *) server_user);
 | ||||
| +	      server_user = xstrdup (arg1);
 | ||||
| +	    }
 | ||||
|  	} | ||||
|        else if (strcmp (entry, "stat-user") == 0) | ||||
|  	{ | ||||
| @@ -198,6 +201,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
 | ||||
|  	    error (0, 0, _("Must specify user name for stat-user option")); | ||||
|  	  else | ||||
|  	    { | ||||
| +	      free ((char *) stat_user);
 | ||||
|  	      stat_user = xstrdup (arg1); | ||||
|   | ||||
|  	      struct passwd *pw = getpwnam (stat_user); | ||||
							
								
								
									
										306
									
								
								SOURCES/glibc-rh1615790.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										306
									
								
								SOURCES/glibc-rh1615790.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,306 @@ | ||||
| commit 2f498f3d140ab5152bd784df2be7af7d9c5e63ed | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Aug 14 10:57:48 2018 +0200 | ||||
| 
 | ||||
|     nss_files: Fix file stream leak in aliases lookup [BZ #23521] | ||||
|      | ||||
|     In order to get a clean test case, it was necessary to fix partially | ||||
|     fixed bug 23522 as well. | ||||
|      | ||||
|     (cherry picked from commit e95c6f61920a0f9237cfb292fa44ad500e1df09b) | ||||
| 
 | ||||
| diff --git a/nss/Makefile b/nss/Makefile
 | ||||
| index 66fac7f5b8a4c0d8..5209fc0456dd6786 100644
 | ||||
| --- a/nss/Makefile
 | ||||
| +++ b/nss/Makefile
 | ||||
| @@ -65,6 +65,7 @@ ifeq (yes,$(build-shared))
 | ||||
|  tests += tst-nss-files-hosts-erange | ||||
|  tests += tst-nss-files-hosts-multi | ||||
|  tests += tst-nss-files-hosts-getent | ||||
| +tests += tst-nss-files-alias-leak
 | ||||
|  endif | ||||
|   | ||||
|  # If we have a thread library then we can test cancellation against | ||||
| @@ -171,3 +172,5 @@ endif
 | ||||
|  $(objpfx)tst-nss-files-hosts-erange: $(libdl) | ||||
|  $(objpfx)tst-nss-files-hosts-multi: $(libdl) | ||||
|  $(objpfx)tst-nss-files-hosts-getent: $(libdl) | ||||
| +$(objpfx)tst-nss-files-alias-leak: $(libdl)
 | ||||
| +$(objpfx)tst-nss-files-alias-leak.out: $(objpfx)/libnss_files.so
 | ||||
| diff --git a/nss/nss_files/files-alias.c b/nss/nss_files/files-alias.c
 | ||||
| index cfd34b66b921bbff..35b0bfc5d2479ab6 100644
 | ||||
| --- a/nss/nss_files/files-alias.c
 | ||||
| +++ b/nss/nss_files/files-alias.c
 | ||||
| @@ -221,6 +221,13 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
 | ||||
|  			{ | ||||
|  			  while (! feof_unlocked (listfile)) | ||||
|  			    { | ||||
| +			      if (room_left < 2)
 | ||||
| +				{
 | ||||
| +				  free (old_line);
 | ||||
| +				  fclose (listfile);
 | ||||
| +				  goto no_more_room;
 | ||||
| +				}
 | ||||
| +
 | ||||
|  			      first_unused[room_left - 1] = '\xff'; | ||||
|  			      line = fgets_unlocked (first_unused, room_left, | ||||
|  						     listfile); | ||||
| @@ -229,6 +236,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
 | ||||
|  			      if (first_unused[room_left - 1] != '\xff') | ||||
|  				{ | ||||
|  				  free (old_line); | ||||
| +				  fclose (listfile);
 | ||||
|  				  goto no_more_room; | ||||
|  				} | ||||
|   | ||||
| @@ -256,6 +264,7 @@ get_next_alias (FILE *stream, const char *match, struct aliasent *result,
 | ||||
|  						       + __alignof__ (char *))) | ||||
|  					{ | ||||
|  					  free (old_line); | ||||
| +					  fclose (listfile);
 | ||||
|  					  goto no_more_room; | ||||
|  					} | ||||
|  				      room_left -= ((first_unused - cp) | ||||
| diff --git a/nss/tst-nss-files-alias-leak.c b/nss/tst-nss-files-alias-leak.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..26d38e2dba1ddaf3
 | ||||
| --- /dev/null
 | ||||
| +++ b/nss/tst-nss-files-alias-leak.c
 | ||||
| @@ -0,0 +1,237 @@
 | ||||
| +/* Check for file descriptor leak in alias :include: processing (bug 23521).
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <aliases.h>
 | ||||
| +#include <array_length.h>
 | ||||
| +#include <dlfcn.h>
 | ||||
| +#include <errno.h>
 | ||||
| +#include <gnu/lib-names.h>
 | ||||
| +#include <nss.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/namespace.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/temp_file.h>
 | ||||
| +#include <support/test-driver.h>
 | ||||
| +#include <support/xstdio.h>
 | ||||
| +#include <support/xunistd.h>
 | ||||
| +
 | ||||
| +static struct support_chroot *chroot_env;
 | ||||
| +
 | ||||
| +/* Number of the aliases for the "many" user.  This must be large
 | ||||
| +   enough to trigger reallocation for the pointer array, but result in
 | ||||
| +   answers below the maximum size tried in do_test.  */
 | ||||
| +enum { many_aliases = 30 };
 | ||||
| +
 | ||||
| +static void
 | ||||
| +prepare (int argc, char **argv)
 | ||||
| +{
 | ||||
| +  chroot_env = support_chroot_create
 | ||||
| +    ((struct support_chroot_configuration) { } );
 | ||||
| +
 | ||||
| +  char *path = xasprintf ("%s/etc/aliases", chroot_env->path_chroot);
 | ||||
| +  add_temp_file (path);
 | ||||
| +  support_write_file_string
 | ||||
| +    (path,
 | ||||
| +     "user1: :include:/etc/aliases.user1\n"
 | ||||
| +     "user2: :include:/etc/aliases.user2\n"
 | ||||
| +     "comment: comment1, :include:/etc/aliases.comment\n"
 | ||||
| +     "many: :include:/etc/aliases.many\n");
 | ||||
| +  free (path);
 | ||||
| +
 | ||||
| +  path = xasprintf ("%s/etc/aliases.user1", chroot_env->path_chroot);
 | ||||
| +  add_temp_file (path);
 | ||||
| +  support_write_file_string (path, "alias1\n");
 | ||||
| +  free (path);
 | ||||
| +
 | ||||
| +  path = xasprintf ("%s/etc/aliases.user2", chroot_env->path_chroot);
 | ||||
| +  add_temp_file (path);
 | ||||
| +  support_write_file_string (path, "alias1a, alias2\n");
 | ||||
| +  free (path);
 | ||||
| +
 | ||||
| +  path = xasprintf ("%s/etc/aliases.comment", chroot_env->path_chroot);
 | ||||
| +  add_temp_file (path);
 | ||||
| +  support_write_file_string
 | ||||
| +    (path,
 | ||||
| +     /* The line must be longer than the line with the :include:
 | ||||
| +        directive in /etc/aliases.  */
 | ||||
| +     "# Long line.  ##############################################\n"
 | ||||
| +     "comment2\n");
 | ||||
| +  free (path);
 | ||||
| +
 | ||||
| +  path = xasprintf ("%s/etc/aliases.many", chroot_env->path_chroot);
 | ||||
| +  add_temp_file (path);
 | ||||
| +  FILE *fp = xfopen (path, "w");
 | ||||
| +  for (int i = 0; i < many_aliases; ++i)
 | ||||
| +    fprintf (fp, "a%d\n", i);
 | ||||
| +  TEST_VERIFY_EXIT (! ferror (fp));
 | ||||
| +  xfclose (fp);
 | ||||
| +  free (path);
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* The names of the users to test.  */
 | ||||
| +static const char *users[] = { "user1", "user2", "comment", "many" };
 | ||||
| +
 | ||||
| +static void
 | ||||
| +check_aliases (int id, const struct aliasent *e)
 | ||||
| +{
 | ||||
| +  TEST_VERIFY_EXIT (id >= 0 || id < array_length (users));
 | ||||
| +  const char *name = users[id];
 | ||||
| +  TEST_COMPARE_BLOB (e->alias_name, strlen (e->alias_name),
 | ||||
| +                     name, strlen (name));
 | ||||
| +
 | ||||
| +  switch (id)
 | ||||
| +    {
 | ||||
| +    case 0:
 | ||||
| +      TEST_COMPARE (e->alias_members_len, 1);
 | ||||
| +      TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
 | ||||
| +                         "alias1", strlen ("alias1"));
 | ||||
| +      break;
 | ||||
| +
 | ||||
| +    case 1:
 | ||||
| +      TEST_COMPARE (e->alias_members_len, 2);
 | ||||
| +      TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
 | ||||
| +                         "alias1a", strlen ("alias1a"));
 | ||||
| +      TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
 | ||||
| +                         "alias2", strlen ("alias2"));
 | ||||
| +      break;
 | ||||
| +
 | ||||
| +    case 2:
 | ||||
| +      TEST_COMPARE (e->alias_members_len, 2);
 | ||||
| +      TEST_COMPARE_BLOB (e->alias_members[0], strlen (e->alias_members[0]),
 | ||||
| +                         "comment1", strlen ("comment1"));
 | ||||
| +      TEST_COMPARE_BLOB (e->alias_members[1], strlen (e->alias_members[1]),
 | ||||
| +                         "comment2", strlen ("comment2"));
 | ||||
| +      break;
 | ||||
| +
 | ||||
| +    case 3:
 | ||||
| +      TEST_COMPARE (e->alias_members_len, many_aliases);
 | ||||
| +      for (int i = 0; i < e->alias_members_len; ++i)
 | ||||
| +        {
 | ||||
| +          char alias[30];
 | ||||
| +          int len = snprintf (alias, sizeof (alias), "a%d", i);
 | ||||
| +          TEST_VERIFY_EXIT (len > 0);
 | ||||
| +          TEST_COMPARE_BLOB (e->alias_members[i], strlen (e->alias_members[i]),
 | ||||
| +                             alias, len);
 | ||||
| +        }
 | ||||
| +      break;
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  /* Make sure we don't try to load the module in the chroot.  */
 | ||||
| +  if (dlopen (LIBNSS_FILES_SO, RTLD_NOW) == NULL)
 | ||||
| +    FAIL_EXIT1 ("could not load " LIBNSS_FILES_SO ": %s", dlerror ());
 | ||||
| +
 | ||||
| +  /* Some of these descriptors will become unavailable if there is a
 | ||||
| +     file descriptor leak.  10 is chosen somewhat arbitrarily.  The
 | ||||
| +     array must be longer than the number of files opened by nss_files
 | ||||
| +     at the same time (currently that number is 2).  */
 | ||||
| +  int next_descriptors[10];
 | ||||
| +  for (size_t i = 0; i < array_length (next_descriptors); ++i)
 | ||||
| +    {
 | ||||
| +      next_descriptors[i] = dup (0);
 | ||||
| +      TEST_VERIFY_EXIT (next_descriptors[i] > 0);
 | ||||
| +    }
 | ||||
| +  for (size_t i = 0; i < array_length (next_descriptors); ++i)
 | ||||
| +    xclose (next_descriptors[i]);
 | ||||
| +
 | ||||
| +  support_become_root ();
 | ||||
| +  if (!support_can_chroot ())
 | ||||
| +    return EXIT_UNSUPPORTED;
 | ||||
| +
 | ||||
| +  __nss_configure_lookup ("aliases", "files");
 | ||||
| +
 | ||||
| +  xchroot (chroot_env->path_chroot);
 | ||||
| +
 | ||||
| +  /* Attempt various buffer sizes.  If the operation succeeds, we
 | ||||
| +     expect correct data.  */
 | ||||
| +  for (int id = 0; id < array_length (users); ++id)
 | ||||
| +    {
 | ||||
| +      bool found = false;
 | ||||
| +      for (size_t size = 1; size <= 1000; ++size)
 | ||||
| +        {
 | ||||
| +          void *buffer = malloc (size);
 | ||||
| +          struct aliasent result;
 | ||||
| +          struct aliasent *res;
 | ||||
| +          errno = EINVAL;
 | ||||
| +          int ret = getaliasbyname_r (users[id], &result, buffer, size, &res);
 | ||||
| +          if (ret == 0)
 | ||||
| +            {
 | ||||
| +              if (res != NULL)
 | ||||
| +                {
 | ||||
| +                  found = true;
 | ||||
| +                  check_aliases (id, res);
 | ||||
| +                }
 | ||||
| +              else
 | ||||
| +                {
 | ||||
| +                  support_record_failure ();
 | ||||
| +                  printf ("error: failed lookup for user \"%s\", size %zu\n",
 | ||||
| +                          users[id], size);
 | ||||
| +                }
 | ||||
| +            }
 | ||||
| +          else if (ret != ERANGE)
 | ||||
| +            {
 | ||||
| +              support_record_failure ();
 | ||||
| +              printf ("error: invalid return code %d (user \%s\", size %zu)\n",
 | ||||
| +                      ret, users[id], size);
 | ||||
| +            }
 | ||||
| +          free (buffer);
 | ||||
| +
 | ||||
| +          /* Make sure that we did not have a file descriptor leak.  */
 | ||||
| +          for (size_t i = 0; i < array_length (next_descriptors); ++i)
 | ||||
| +            {
 | ||||
| +              int new_fd = dup (0);
 | ||||
| +              if (new_fd != next_descriptors[i])
 | ||||
| +                {
 | ||||
| +                  support_record_failure ();
 | ||||
| +                  printf ("error: descriptor %d at index %zu leaked"
 | ||||
| +                          " (user \"%s\", size %zu)\n",
 | ||||
| +                          next_descriptors[i], i, users[id], size);
 | ||||
| +
 | ||||
| +                  /* Close unexpected descriptor, the leak probing
 | ||||
| +                     descriptors, and the leaked descriptor
 | ||||
| +                     next_descriptors[i].  */
 | ||||
| +                  xclose (new_fd);
 | ||||
| +                  for (size_t j = 0; j <= i; ++j)
 | ||||
| +                    xclose (next_descriptors[j]);
 | ||||
| +                  goto next_size;
 | ||||
| +                }
 | ||||
| +            }
 | ||||
| +          for (size_t i = 0; i < array_length (next_descriptors); ++i)
 | ||||
| +            xclose (next_descriptors[i]);
 | ||||
| +
 | ||||
| +        next_size:
 | ||||
| +          ;
 | ||||
| +        }
 | ||||
| +      if (!found)
 | ||||
| +        {
 | ||||
| +          support_record_failure ();
 | ||||
| +          printf ("error: user %s not found\n", users[id]);
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  support_chroot_free (chroot_env);
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define PREPARE prepare
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										27
									
								
								SOURCES/glibc-rh1622675.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								SOURCES/glibc-rh1622675.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,27 @@ | ||||
| commit aa8a3e4cdef20c50cb20f008864fff05cbfbdf29 | ||||
| Author: Martin Kuchta <martin.kuchta@netapp.com> | ||||
| Date:   Mon Aug 27 18:54:46 2018 +0200 | ||||
| 
 | ||||
|     pthread_cond_broadcast: Fix waiters-after-spinning case [BZ #23538] | ||||
|      | ||||
|     (cherry picked from commit 99ea93ca31795469d2a1f1570f17a5c39c2eb7e2) | ||||
| 
 | ||||
| diff --git a/nptl/pthread_cond_common.c b/nptl/pthread_cond_common.c
 | ||||
| index 8e425eb01eceabec..479e54febb417675 100644
 | ||||
| --- a/nptl/pthread_cond_common.c
 | ||||
| +++ b/nptl/pthread_cond_common.c
 | ||||
| @@ -405,8 +405,12 @@ __condvar_quiesce_and_switch_g1 (pthread_cond_t *cond, uint64_t wseq,
 | ||||
|  	{ | ||||
|  	  /* There is still a waiter after spinning.  Set the wake-request | ||||
|  	     flag and block.  Relaxed MO is fine because this is just about | ||||
| -	     this futex word.  */
 | ||||
| -	  r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1);
 | ||||
| +	     this futex word.
 | ||||
| +
 | ||||
| +	     Update r to include the set wake-request flag so that the upcoming
 | ||||
| +	     futex_wait only blocks if the flag is still set (otherwise, we'd
 | ||||
| +	     violate the basic client-side futex protocol).  */
 | ||||
| +	  r = atomic_fetch_or_relaxed (cond->__data.__g_refs + g1, 1) | 1;
 | ||||
|   | ||||
|  	  if ((r >> 1) > 0) | ||||
|  	    futex_wait_simple (cond->__data.__g_refs + g1, r, private); | ||||
							
								
								
									
										41
									
								
								SOURCES/glibc-rh1622678-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								SOURCES/glibc-rh1622678-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| commit 58559f14437d2aa71753a29fed435efa06aa4576 | ||||
| Author: Paul Eggert <eggert@cs.ucla.edu> | ||||
| Date:   Tue Aug 28 21:54:28 2018 +0200 | ||||
| 
 | ||||
|     regex: fix uninitialized memory access | ||||
|      | ||||
|     I introduced this bug into gnulib in commit | ||||
|     8335a4d6c7b4448cd0bcb6d0bebf1d456bcfdb17 dated 2006-04-10; | ||||
|     eventually it was merged into glibc.  The bug was found by | ||||
|     project-repo <bugs@feusi.co> and reported here: | ||||
|     https://lists.gnu.org/r/sed-devel/2018-08/msg00017.html | ||||
|     Diagnosis and draft fix reported by Assaf Gordon here: | ||||
|     https://lists.gnu.org/r/bug-gnulib/2018-08/msg00071.html | ||||
|     https://lists.gnu.org/r/bug-gnulib/2018-08/msg00142.html | ||||
|     * posix/regex_internal.c (build_wcs_upper_buffer): | ||||
|     Fix bug when mbrtowc returns 0. | ||||
|      | ||||
|     (cherry picked from commit bc680b336971305cb39896b30d72dc7101b62242) | ||||
| 
 | ||||
| diff --git a/posix/regex_internal.c b/posix/regex_internal.c
 | ||||
| index 7f0083b918de6530..b10588f1ccbb1992 100644
 | ||||
| --- a/posix/regex_internal.c
 | ||||
| +++ b/posix/regex_internal.c
 | ||||
| @@ -317,7 +317,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
 | ||||
|  	  mbclen = __mbrtowc (&wc, | ||||
|  			      ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx | ||||
|  			       + byte_idx), remain_len, &pstr->cur_state); | ||||
| -	  if (BE (mbclen < (size_t) -2, 1))
 | ||||
| +	  if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
 | ||||
|  	    { | ||||
|  	      wchar_t wcu = __towupper (wc); | ||||
|  	      if (wcu != wc) | ||||
| @@ -386,7 +386,7 @@ build_wcs_upper_buffer (re_string_t *pstr)
 | ||||
|  	else | ||||
|  	  p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; | ||||
|  	mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); | ||||
| -	if (BE (mbclen < (size_t) -2, 1))
 | ||||
| +	if (BE (0 < mbclen && mbclen < (size_t) -2, 1))
 | ||||
|  	  { | ||||
|  	    wchar_t wcu = __towupper (wc); | ||||
|  	    if (wcu != wc) | ||||
							
								
								
									
										226
									
								
								SOURCES/glibc-rh1622678-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										226
									
								
								SOURCES/glibc-rh1622678-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,226 @@ | ||||
| commit 0b79004569e5ce1669136b8c41564c3809730f15 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Aug 28 12:57:46 2018 +0200 | ||||
| 
 | ||||
|     regex: Add test tst-regcomp-truncated [BZ #23578] | ||||
|      | ||||
|     (cherry picked from commit 761404b74d9853ce1608195e24f25b78a910591a) | ||||
| 
 | ||||
| diff --git a/posix/Makefile b/posix/Makefile
 | ||||
| index 00c62841a282f15a..83162123f9c927a0 100644
 | ||||
| --- a/posix/Makefile
 | ||||
| +++ b/posix/Makefile
 | ||||
| @@ -96,7 +96,7 @@ tests		:= test-errno tstgetopt testfnm runtests runptests \
 | ||||
|  		   tst-posix_fadvise tst-posix_fadvise64 \ | ||||
|  		   tst-sysconf-empty-chroot tst-glob_symlinks tst-fexecve \ | ||||
|  		   tst-glob-tilde test-ssize-max tst-spawn4 bug-regex37 \ | ||||
| -		   bug-regex38
 | ||||
| +		   bug-regex38 tst-regcomp-truncated
 | ||||
|  tests-internal	:= bug-regex5 bug-regex20 bug-regex33 \ | ||||
|  		   tst-rfc3484 tst-rfc3484-2 tst-rfc3484-3 \ | ||||
|  		   tst-glob_lstat_compat tst-spawn4-compat | ||||
| @@ -194,6 +194,7 @@ $(objpfx)tst-regex2.out: $(gen-locales)
 | ||||
|  $(objpfx)tst-regexloc.out: $(gen-locales) | ||||
|  $(objpfx)tst-rxspencer.out: $(gen-locales) | ||||
|  $(objpfx)tst-rxspencer-no-utf8.out: $(gen-locales) | ||||
| +$(objpfx)tst-regcomp-truncated.out: $(gen-locales)
 | ||||
|  endif | ||||
|   | ||||
|  # If we will use the generic uname implementation, we must figure out what | ||||
| diff --git a/posix/tst-regcomp-truncated.c b/posix/tst-regcomp-truncated.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..a4a1581bbc2b39eb
 | ||||
| --- /dev/null
 | ||||
| +++ b/posix/tst-regcomp-truncated.c
 | ||||
| @@ -0,0 +1,191 @@
 | ||||
| +/* Test compilation of truncated regular expressions.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* This test constructs various patterns in an attempt to trigger
 | ||||
| +   over-reading the regular expression compiler, such as bug
 | ||||
| +   23578.  */
 | ||||
| +
 | ||||
| +#include <array_length.h>
 | ||||
| +#include <errno.h>
 | ||||
| +#include <locale.h>
 | ||||
| +#include <regex.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/next_to_fault.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/test-driver.h>
 | ||||
| +#include <wchar.h>
 | ||||
| +
 | ||||
| +/* Locales to test.  */
 | ||||
| +static const char locales[][17] =
 | ||||
| +  {
 | ||||
| +    "C",
 | ||||
| +    "en_US.UTF-8",
 | ||||
| +    "de_DE.ISO-8859-1",
 | ||||
| +  };
 | ||||
| +
 | ||||
| +/* Syntax options.  Will be combined with other flags.  */
 | ||||
| +static const reg_syntax_t syntaxes[] =
 | ||||
| +  {
 | ||||
| +    RE_SYNTAX_EMACS,
 | ||||
| +    RE_SYNTAX_AWK,
 | ||||
| +    RE_SYNTAX_GNU_AWK,
 | ||||
| +    RE_SYNTAX_POSIX_AWK,
 | ||||
| +    RE_SYNTAX_GREP,
 | ||||
| +    RE_SYNTAX_EGREP,
 | ||||
| +    RE_SYNTAX_POSIX_EGREP,
 | ||||
| +    RE_SYNTAX_POSIX_BASIC,
 | ||||
| +    RE_SYNTAX_POSIX_EXTENDED,
 | ||||
| +    RE_SYNTAX_POSIX_MINIMAL_EXTENDED,
 | ||||
| +  };
 | ||||
| +
 | ||||
| +/* Trailing characters placed after the initial character.  */
 | ||||
| +static const char trailing_strings[][4] =
 | ||||
| +  {
 | ||||
| +    "",
 | ||||
| +    "[",
 | ||||
| +    "\\",
 | ||||
| +    "[\\",
 | ||||
| +    "(",
 | ||||
| +    "(\\",
 | ||||
| +    "\\(",
 | ||||
| +  };
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  /* Staging buffer for the constructed regular expression.  */
 | ||||
| +  char buffer[16];
 | ||||
| +
 | ||||
| +  /* Allocation used to detect over-reading by the regular expression
 | ||||
| +     compiler.  */
 | ||||
| +  struct support_next_to_fault ntf
 | ||||
| +    = support_next_to_fault_allocate (sizeof (buffer));
 | ||||
| +
 | ||||
| +  /* Arbitrary Unicode codepoint at which we stop generating
 | ||||
| +     characters.  We do not probe the whole range because that would
 | ||||
| +     take too long due to combinatorical exploision as the result of
 | ||||
| +     combination with other flags.  */
 | ||||
| +  static const wchar_t last_character = 0xfff;
 | ||||
| +
 | ||||
| +  for (size_t locale_idx = 0; locale_idx < array_length (locales);
 | ||||
| +       ++ locale_idx)
 | ||||
| +    {
 | ||||
| +      if (setlocale (LC_ALL, locales[locale_idx]) == NULL)
 | ||||
| +        {
 | ||||
| +          support_record_failure ();
 | ||||
| +          printf ("error: setlocale (\"%s\"): %m", locales[locale_idx]);
 | ||||
| +          continue;
 | ||||
| +        }
 | ||||
| +      if (test_verbose > 0)
 | ||||
| +        printf ("info: testing locale \"%s\"\n", locales[locale_idx]);
 | ||||
| +
 | ||||
| +      for (wchar_t wc = 0; wc <= last_character; ++wc)
 | ||||
| +        {
 | ||||
| +          char *after_wc;
 | ||||
| +          if (wc == 0)
 | ||||
| +            {
 | ||||
| +              /* wcrtomb treats L'\0' in a special way.  */
 | ||||
| +              *buffer = '\0';
 | ||||
| +              after_wc = &buffer[1];
 | ||||
| +            }
 | ||||
| +          else
 | ||||
| +            {
 | ||||
| +              mbstate_t ps = { };
 | ||||
| +              size_t ret = wcrtomb (buffer, wc, &ps);
 | ||||
| +              if (ret == (size_t) -1)
 | ||||
| +                {
 | ||||
| +                  /* EILSEQ means that the target character set
 | ||||
| +                     cannot encode the character.  */
 | ||||
| +                  if (errno != EILSEQ)
 | ||||
| +                    {
 | ||||
| +                      support_record_failure ();
 | ||||
| +                      printf ("error: wcrtomb (0x%x) failed: %m\n",
 | ||||
| +                              (unsigned) wc);
 | ||||
| +                    }
 | ||||
| +                  continue;
 | ||||
| +                }
 | ||||
| +              TEST_VERIFY_EXIT (ret != 0);
 | ||||
| +              after_wc = &buffer[ret];
 | ||||
| +            }
 | ||||
| +
 | ||||
| +          for (size_t trailing_idx = 0;
 | ||||
| +               trailing_idx < array_length (trailing_strings);
 | ||||
| +               ++trailing_idx)
 | ||||
| +            {
 | ||||
| +              char *after_trailing
 | ||||
| +                = stpcpy (after_wc, trailing_strings[trailing_idx]);
 | ||||
| +
 | ||||
| +              for (int do_nul = 0; do_nul < 2; ++do_nul)
 | ||||
| +                {
 | ||||
| +                  char *after_nul;
 | ||||
| +                  if (do_nul)
 | ||||
| +                    {
 | ||||
| +                      *after_trailing = '\0';
 | ||||
| +                      after_nul = &after_trailing[1];
 | ||||
| +                    }
 | ||||
| +                  else
 | ||||
| +                    after_nul = after_trailing;
 | ||||
| +
 | ||||
| +                  size_t length = after_nul - buffer;
 | ||||
| +
 | ||||
| +                  /* Make sure that the faulting region starts
 | ||||
| +                     after the used portion of the buffer.  */
 | ||||
| +                  char *ntf_start = ntf.buffer + sizeof (buffer) - length;
 | ||||
| +                  memcpy (ntf_start, buffer, length);
 | ||||
| +
 | ||||
| +                  for (const reg_syntax_t *psyntax = syntaxes;
 | ||||
| +                       psyntax < array_end (syntaxes); ++psyntax)
 | ||||
| +                    for (int do_icase = 0; do_icase < 2; ++do_icase)
 | ||||
| +                      {
 | ||||
| +                        re_syntax_options = *psyntax;
 | ||||
| +                        if (do_icase)
 | ||||
| +                          re_syntax_options |= RE_ICASE;
 | ||||
| +
 | ||||
| +                        regex_t reg;
 | ||||
| +                        memset (®, 0, sizeof (reg));
 | ||||
| +                        const char *msg = re_compile_pattern
 | ||||
| +                          (ntf_start, length, ®);
 | ||||
| +                        if (msg != NULL)
 | ||||
| +                          {
 | ||||
| +                            if (test_verbose > 0)
 | ||||
| +                              {
 | ||||
| +                                char *quoted = support_quote_blob
 | ||||
| +                                  (buffer, length);
 | ||||
| +                                printf ("info: compilation failed for pattern"
 | ||||
| +                                        " \"%s\", syntax 0x%lx: %s\n",
 | ||||
| +                                        quoted, re_syntax_options, msg);
 | ||||
| +                                free (quoted);
 | ||||
| +                              }
 | ||||
| +                          }
 | ||||
| +                        else
 | ||||
| +                          regfree (®);
 | ||||
| +                      }
 | ||||
| +                }
 | ||||
| +            }
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  support_next_to_fault_free (&ntf);
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										34
									
								
								SOURCES/glibc-rh1623536-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								SOURCES/glibc-rh1623536-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| commit 3a67c72c1512f778304a5644dea2fcf5bdece274 | ||||
| Author: Andreas Schwab <schwab@suse.de> | ||||
| Date:   Thu Sep 27 12:37:06 2018 +0200 | ||||
| 
 | ||||
|     Fix stack overflow in tst-setcontext9 (bug 23717) | ||||
|      | ||||
|     The function f1a, executed on a stack of size 32k, allocates an object of | ||||
|     size 32k on the stack.  Make the stack variables static to reduce | ||||
|     excessive stack usage. | ||||
|      | ||||
|     (cherry picked from commit f841c97e515a1673485a2b12b3c280073d737890) | ||||
| 
 | ||||
| diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
 | ||||
| index db8355766ca7b906..009928235dd5987e 100644
 | ||||
| --- a/stdlib/tst-setcontext9.c
 | ||||
| +++ b/stdlib/tst-setcontext9.c
 | ||||
| @@ -58,7 +58,7 @@ f1b (void)
 | ||||
|  static void | ||||
|  f1a (void) | ||||
|  { | ||||
| -  char st2[32768];
 | ||||
| +  static char st2[32768];
 | ||||
|    puts ("start f1a"); | ||||
|    if (getcontext (&ctx[2]) != 0) | ||||
|      { | ||||
| @@ -93,7 +93,7 @@ f1a (void)
 | ||||
|  static int | ||||
|  do_test (void) | ||||
|  { | ||||
| -  char st1[32768];
 | ||||
| +  static char st1[32768];
 | ||||
|    puts ("making contexts"); | ||||
|    if (getcontext (&ctx[0]) != 0) | ||||
|      { | ||||
							
								
								
									
										100
									
								
								SOURCES/glibc-rh1623536.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								SOURCES/glibc-rh1623536.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| commit a55e109709af55e6ed67d3f9536cac5d929c982e | ||||
| Author: Carlos O'Donell <carlos@redhat.com> | ||||
| Date:   Wed Sep 5 01:16:42 2018 -0400 | ||||
| 
 | ||||
|     Fix tst-setcontext9 for optimized small stacks. | ||||
|      | ||||
|     If the compiler reduces the stack usage in function f1 before calling | ||||
|     into function f2, then when we swapcontext back to f1 and continue | ||||
|     execution we may overwrite registers that were spilled to the stack | ||||
|     while f2 was executing.  Later when we return to f2 the corrupt | ||||
|     registers will be reloaded from the stack and the test will crash.  This | ||||
|     was most commonly observed on i686 with __x86.get_pc_thunk.dx and | ||||
|     needing to save and restore $edx.  Overall i686 has few registers and | ||||
|     the spilling to the stack is bound to happen, therefore the solution to | ||||
|     making this test robust is to split function f1 into two parts f1a and | ||||
|     f1b, and allocate f1b it's own stack such that subsequent execution does | ||||
|     not overwrite the stack in use by function f2. | ||||
|      | ||||
|     Tested on i686 and x86_64. | ||||
|      | ||||
|     Signed-off-by: Carlos O'Donell <carlos@redhat.com> | ||||
|     (cherry picked from commit 791b350dc725545e3f9b5db0f97ebdbc60c9735f) | ||||
| 
 | ||||
| diff --git a/stdlib/tst-setcontext9.c b/stdlib/tst-setcontext9.c
 | ||||
| index 4636ce9030fa38a7..db8355766ca7b906 100644
 | ||||
| --- a/stdlib/tst-setcontext9.c
 | ||||
| +++ b/stdlib/tst-setcontext9.c
 | ||||
| @@ -41,26 +41,55 @@ f2 (void)
 | ||||
|  } | ||||
|   | ||||
|  static void | ||||
| -f1 (void)
 | ||||
| +f1b (void)
 | ||||
|  { | ||||
| -  puts ("start f1");
 | ||||
| -  if (getcontext (&ctx[2]) != 0)
 | ||||
| -    {
 | ||||
| -      printf ("%s: getcontext: %m\n", __FUNCTION__);
 | ||||
| -      exit (EXIT_FAILURE);
 | ||||
| -    }
 | ||||
|    if (done) | ||||
|      { | ||||
| -      puts ("set context in f1");
 | ||||
| +      puts ("set context in f1b");
 | ||||
|        if (setcontext (&ctx[3]) != 0) | ||||
|  	{ | ||||
|  	  printf ("%s: setcontext: %m\n", __FUNCTION__); | ||||
|  	  exit (EXIT_FAILURE); | ||||
|  	} | ||||
|      } | ||||
| +  exit (EXIT_FAILURE);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +f1a (void)
 | ||||
| +{
 | ||||
| +  char st2[32768];
 | ||||
| +  puts ("start f1a");
 | ||||
| +  if (getcontext (&ctx[2]) != 0)
 | ||||
| +    {
 | ||||
| +      printf ("%s: getcontext: %m\n", __FUNCTION__);
 | ||||
| +      exit (EXIT_FAILURE);
 | ||||
| +    }
 | ||||
| +  ctx[2].uc_stack.ss_sp = st2;
 | ||||
| +  ctx[2].uc_stack.ss_size = sizeof st2;
 | ||||
| +  ctx[2].uc_link = &ctx[0];
 | ||||
| +  makecontext (&ctx[2], (void (*) (void)) f1b, 0);
 | ||||
|    f2 (); | ||||
|  } | ||||
|   | ||||
| +/* The execution path through the test looks like this:
 | ||||
| +   do_test (call)
 | ||||
| +   -> "making contexts"
 | ||||
| +   -> "swap contexts"
 | ||||
| +   f1a (via swapcontext to ctx[1], with alternate stack)
 | ||||
| +   -> "start f1a"
 | ||||
| +   f2 (call)
 | ||||
| +   -> "swap contexts in f2"
 | ||||
| +   f1b (via swapcontext to ctx[2], with alternate stack)
 | ||||
| +   -> "set context in f1b"
 | ||||
| +   do_test (via setcontext to ctx[3], main stack)
 | ||||
| +   -> "setcontext"
 | ||||
| +   f2 (via setcontext to ctx[4], with alternate stack)
 | ||||
| +   -> "end f2"
 | ||||
| +
 | ||||
| +   We must use an alternate stack for f1b, because if we don't then the
 | ||||
| +   result of executing an earlier caller may overwrite registers
 | ||||
| +   spilled to the stack in f2.  */
 | ||||
|  static int | ||||
|  do_test (void) | ||||
|  { | ||||
| @@ -79,7 +108,7 @@ do_test (void)
 | ||||
|    ctx[1].uc_stack.ss_sp = st1; | ||||
|    ctx[1].uc_stack.ss_size = sizeof st1; | ||||
|    ctx[1].uc_link = &ctx[0]; | ||||
| -  makecontext (&ctx[1], (void (*) (void)) f1, 0);
 | ||||
| +  makecontext (&ctx[1], (void (*) (void)) f1a, 0);
 | ||||
|    puts ("swap contexts"); | ||||
|    if (swapcontext (&ctx[3], &ctx[1]) != 0) | ||||
|      { | ||||
							
								
								
									
										61
									
								
								SOURCES/glibc-rh1623537.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								SOURCES/glibc-rh1623537.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| commit b297581acb66f80b513996c1580158b0fb12d469 | ||||
| Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | ||||
| Date:   Mon Jan 14 17:54:44 2019 -0200 | ||||
| 
 | ||||
|     Add XFAIL_ROUNDING_IBM128_LIBGCC to more fma() tests | ||||
|      | ||||
|     Ignore 16 errors in math/test-ldouble-fma and 4 errors in | ||||
|     math/test-ildouble-fma when IBM 128-bit long double used. | ||||
|     These errors are caused by spurious overflows from libgcc. | ||||
|      | ||||
|             * math/libm-test-fma.inc (fma_test_data): Set | ||||
|             XFAIL_ROUNDING_IBM128_LIBGCC to more tests. | ||||
|      | ||||
|     Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | ||||
|     (cherry picked from commit ecdacd34a2ac3b6d5a529ff218b29261d9d98a7a) | ||||
| 
 | ||||
| diff --git a/math/libm-test-fma.inc b/math/libm-test-fma.inc
 | ||||
| index 5b29fb820194e055..a7ee40992420c1ab 100644
 | ||||
| --- a/math/libm-test-fma.inc
 | ||||
| +++ b/math/libm-test-fma.inc
 | ||||
| @@ -119,32 +119,32 @@ static const struct test_fff_f_data fma_test_data[] =
 | ||||
|      TEST_fff_f (fma, plus_infty, plus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, plus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, plus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
| -    TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| -    TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| +    TEST_fff_f (fma, plus_infty, plus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
| +    TEST_fff_f (fma, plus_infty, plus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
|      TEST_fff_f (fma, plus_infty, minus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, minus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, minus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, minus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, minus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, plus_infty, minus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
| -    TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| -    TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| +    TEST_fff_f (fma, plus_infty, minus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
| +    TEST_fff_f (fma, plus_infty, minus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
|      TEST_fff_f (fma, minus_infty, plus_infty, plus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, plus_infty, minus_zero, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, plus_infty, min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, plus_infty, -min_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, plus_infty, min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, plus_infty, -min_subnorm_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
| -    TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| -    TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| +    TEST_fff_f (fma, minus_infty, plus_infty, max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
| +    TEST_fff_f (fma, minus_infty, plus_infty, -max_value, minus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
|      TEST_fff_f (fma, minus_infty, minus_infty, plus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, minus_infty, minus_zero, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, minus_infty, min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, minus_infty, -min_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, minus_infty, min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
|      TEST_fff_f (fma, minus_infty, minus_infty, -min_subnorm_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED), | ||||
| -    TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| -    TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
 | ||||
| +    TEST_fff_f (fma, minus_infty, minus_infty, max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
| +    TEST_fff_f (fma, minus_infty, minus_infty, -max_value, plus_infty, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|XFAIL_ROUNDING_IBM128_LIBGCC),
 | ||||
|   | ||||
|      AUTO_TESTS_fff_f (fma), | ||||
|    }; | ||||
							
								
								
									
										29
									
								
								SOURCES/glibc-rh1631293-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								SOURCES/glibc-rh1631293-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,29 @@ | ||||
| commit e7d22db29cfdd2f1fb97a70a76fa53d151569945 | ||||
| Author: Mingli Yu <Mingli.Yu@windriver.com> | ||||
| Date:   Thu Sep 20 12:41:13 2018 +0200 | ||||
| 
 | ||||
|     Linux gethostid: Check for NULL value from gethostbyname_r [BZ #23679] | ||||
|      | ||||
|     A NULL value can happen with certain gethostbyname_r failures. | ||||
|      | ||||
|     (cherry picked from commit 1214ba06e6771acb953a190091b0f6055c64fd25) | ||||
| 
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/gethostid.c b/sysdeps/unix/sysv/linux/gethostid.c
 | ||||
| index 2e20f034dc134cc7..ee0190e7f945db1f 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/gethostid.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/gethostid.c
 | ||||
| @@ -102,12 +102,12 @@ gethostid (void)
 | ||||
|      { | ||||
|        int ret = __gethostbyname_r (hostname, &hostbuf, | ||||
|  				   tmpbuf.data, tmpbuf.length, &hp, &herr); | ||||
| -      if (ret == 0)
 | ||||
| +      if (ret == 0 && hp != NULL)
 | ||||
|  	break; | ||||
|        else | ||||
|  	{ | ||||
|  	  /* Enlarge the buffer on ERANGE.  */ | ||||
| -	  if (herr == NETDB_INTERNAL && errno == ERANGE)
 | ||||
| +	  if (ret != 0 && herr == NETDB_INTERNAL && errno == ERANGE)
 | ||||
|  	    { | ||||
|  	      if (!scratch_buffer_grow (&tmpbuf)) | ||||
|  		return 0; | ||||
							
								
								
									
										146
									
								
								SOURCES/glibc-rh1631293-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										146
									
								
								SOURCES/glibc-rh1631293-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,146 @@ | ||||
| commit 307d04334d516bb180f484a2b283f97310bfee66 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Thu Sep 20 12:03:01 2018 +0200 | ||||
| 
 | ||||
|     misc: New test misc/tst-gethostid | ||||
|      | ||||
|     The empty /etc/hosts file used to trigger bug 23679. | ||||
|      | ||||
|     (cherry picked from commit db9a8ad4ff3fc58e3773a9a4d0cabe3c1bc9c94c) | ||||
| 
 | ||||
| diff --git a/misc/Makefile b/misc/Makefile
 | ||||
| index b7be2bc19a6f7ed5..c9f81515ac9aef2c 100644
 | ||||
| --- a/misc/Makefile
 | ||||
| +++ b/misc/Makefile
 | ||||
| @@ -86,6 +86,11 @@ tests := tst-dirname tst-tsearch tst-fdset tst-efgcvt tst-mntent tst-hsearch \
 | ||||
|  	 tst-preadvwritev tst-preadvwritev64 tst-makedev tst-empty \ | ||||
|  	 tst-preadvwritev2 tst-preadvwritev64v2 | ||||
|   | ||||
| +# Tests which need libdl.
 | ||||
| +ifeq (yes,$(build-shared))
 | ||||
| +tests += tst-gethostid
 | ||||
| +endif
 | ||||
| +
 | ||||
|  tests-internal := tst-atomic tst-atomic-long tst-allocate_once | ||||
|  tests-static := tst-empty | ||||
|   | ||||
| @@ -145,3 +150,5 @@ tst-allocate_once-ENV = MALLOC_TRACE=$(objpfx)tst-allocate_once.mtrace
 | ||||
|  $(objpfx)tst-allocate_once-mem.out: $(objpfx)tst-allocate_once.out | ||||
|  	$(common-objpfx)malloc/mtrace $(objpfx)tst-allocate_once.mtrace > $@; \ | ||||
|  	$(evaluate-test) | ||||
| +
 | ||||
| +$(objpfx)tst-gethostid: $(libdl)
 | ||||
| diff --git a/misc/tst-gethostid.c b/misc/tst-gethostid.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..1490aaf3f517ff1d
 | ||||
| --- /dev/null
 | ||||
| +++ b/misc/tst-gethostid.c
 | ||||
| @@ -0,0 +1,108 @@
 | ||||
| +/* Basic test for gethostid.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <gnu/lib-names.h>
 | ||||
| +#include <nss.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/namespace.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/temp_file.h>
 | ||||
| +#include <support/xdlfcn.h>
 | ||||
| +#include <support/xstdio.h>
 | ||||
| +#include <support/xunistd.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +
 | ||||
| +/* Initial test is run outside a chroot, to increase the likelihood of
 | ||||
| +   success.  */
 | ||||
| +static void
 | ||||
| +outside_chroot (void *closure)
 | ||||
| +{
 | ||||
| +  long id = gethostid ();
 | ||||
| +  printf ("info: host ID outside chroot: 0x%lx\n", id);
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* The same, but this time perform a chroot operation.  */
 | ||||
| +static void
 | ||||
| +in_chroot (void *closure)
 | ||||
| +{
 | ||||
| +  const char *chroot_path = closure;
 | ||||
| +  xchroot (chroot_path);
 | ||||
| +  long id = gethostid ();
 | ||||
| +  printf ("info: host ID in chroot: 0x%lx\n", id);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  support_isolate_in_subprocess (outside_chroot, NULL);
 | ||||
| +
 | ||||
| +  /* Now run the test inside a chroot.  */
 | ||||
| +  support_become_root ();
 | ||||
| +  if (!support_can_chroot ())
 | ||||
| +    /* Cannot perform further tests.  */
 | ||||
| +    return 0;
 | ||||
| +
 | ||||
| +  /* Only use nss_files.  */
 | ||||
| +  __nss_configure_lookup ("hosts", "files");
 | ||||
| +
 | ||||
| +  /* Load the DSO outside of the chroot.  */
 | ||||
| +  xdlopen (LIBNSS_FILES_SO, RTLD_LAZY);
 | ||||
| +
 | ||||
| +  char *chroot_dir = support_create_temp_directory ("tst-gethostid-");
 | ||||
| +  support_isolate_in_subprocess (in_chroot, chroot_dir);
 | ||||
| +
 | ||||
| +  /* Tests with /etc/hosts in the chroot.  */
 | ||||
| +  {
 | ||||
| +    char *path = xasprintf ("%s/etc", chroot_dir);
 | ||||
| +    add_temp_file (path);
 | ||||
| +    xmkdir (path, 0777);
 | ||||
| +    free (path);
 | ||||
| +    path = xasprintf ("%s/etc/hosts", chroot_dir);
 | ||||
| +    add_temp_file (path);
 | ||||
| +
 | ||||
| +    FILE *fp = xfopen (path, "w");
 | ||||
| +    xfclose (fp);
 | ||||
| +    printf ("info: chroot test with an empty /etc/hosts file\n");
 | ||||
| +    support_isolate_in_subprocess (in_chroot, chroot_dir);
 | ||||
| +
 | ||||
| +    char hostname[1024];
 | ||||
| +    int ret = gethostname (hostname, sizeof (hostname));
 | ||||
| +    if (ret < 0)
 | ||||
| +      printf ("warning: invalid result from gethostname: %d\n", ret);
 | ||||
| +    else if (strlen (hostname) == 0)
 | ||||
| +      puts ("warning: gethostname returned empty string");
 | ||||
| +    else
 | ||||
| +      {
 | ||||
| +        printf ("info: chroot test with IPv6 address in /etc/hosts for: %s\n",
 | ||||
| +                hostname);
 | ||||
| +        fp = xfopen (path, "w");
 | ||||
| +        /* Use an IPv6 address to induce another lookup failure.  */
 | ||||
| +        fprintf (fp, "2001:db8::1 %s\n", hostname);
 | ||||
| +        xfclose (fp);
 | ||||
| +        support_isolate_in_subprocess (in_chroot, chroot_dir);
 | ||||
| +      }
 | ||||
| +    free (path);
 | ||||
| +  }
 | ||||
| +  free (chroot_dir);
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										108
									
								
								SOURCES/glibc-rh1631722.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								SOURCES/glibc-rh1631722.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,108 @@ | ||||
| commit 0ef2f4400c06927af34c515555f68840a70ba409 | ||||
| Author: Wilco Dijkstra <wdijkstr@arm.com> | ||||
| Date:   Wed Sep 19 16:50:18 2018 +0100 | ||||
| 
 | ||||
|     Fix strstr bug with huge needles (bug 23637) | ||||
|      | ||||
|     The generic strstr in GLIBC 2.28 fails to match huge needles.  The optimized | ||||
|     AVAILABLE macro reads ahead a large fixed amount to reduce the overhead of | ||||
|     repeatedly checking for the end of the string.  However if the needle length | ||||
|     is larger than this, two_way_long_needle may confuse this as meaning the end | ||||
|     of the string and return NULL.  This is fixed by adding the needle length to | ||||
|     the amount to read ahead. | ||||
|      | ||||
|             [BZ #23637] | ||||
|             * string/test-strstr.c (pr23637): New function. | ||||
|             (test_main): Add tests with longer needles. | ||||
|             * string/strcasestr.c (AVAILABLE): Fix readahead distance. | ||||
|             * string/strstr.c (AVAILABLE): Likewise. | ||||
|      | ||||
|         (cherry picked from commit 83a552b0bb9fc2a5e80a0ab3723c0a80ce1db9f2) | ||||
| 
 | ||||
| diff --git a/string/strcasestr.c b/string/strcasestr.c
 | ||||
| index 5909fe3cdba88e47..421764bd1b0ff22e 100644
 | ||||
| --- a/string/strcasestr.c
 | ||||
| +++ b/string/strcasestr.c
 | ||||
| @@ -37,8 +37,9 @@
 | ||||
|  /* Two-Way algorithm.  */ | ||||
|  #define RETURN_TYPE char * | ||||
|  #define AVAILABLE(h, h_l, j, n_l)			\ | ||||
| -  (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
 | ||||
| -			      (j) + (n_l) <= (h_l)))
 | ||||
| +  (((j) + (n_l) <= (h_l)) \
 | ||||
| +   || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
 | ||||
| +       (j) + (n_l) <= (h_l)))
 | ||||
|  #define CHECK_EOL (1) | ||||
|  #define RET0_IF_0(a) if (!a) goto ret0 | ||||
|  #define CANON_ELEMENT(c) TOLOWER (c) | ||||
| diff --git a/string/strstr.c b/string/strstr.c
 | ||||
| index 265e9f310ce507ce..79ebcc75329d0b17 100644
 | ||||
| --- a/string/strstr.c
 | ||||
| +++ b/string/strstr.c
 | ||||
| @@ -33,8 +33,9 @@
 | ||||
|   | ||||
|  #define RETURN_TYPE char * | ||||
|  #define AVAILABLE(h, h_l, j, n_l)			\ | ||||
| -  (((j) + (n_l) <= (h_l)) || ((h_l) += __strnlen ((void*)((h) + (h_l)), 512), \
 | ||||
| -			      (j) + (n_l) <= (h_l)))
 | ||||
| +  (((j) + (n_l) <= (h_l)) \
 | ||||
| +   || ((h_l) += __strnlen ((void*)((h) + (h_l)), (n_l) + 512), \
 | ||||
| +       (j) + (n_l) <= (h_l)))
 | ||||
|  #define CHECK_EOL (1) | ||||
|  #define RET0_IF_0(a) if (!a) goto ret0 | ||||
|  #define FASTSEARCH(S,C,N) (void*) strchr ((void*)(S), (C)) | ||||
| diff --git a/string/test-strstr.c b/string/test-strstr.c
 | ||||
| index 8d99716ff39cc2c2..5861b01b73e4c315 100644
 | ||||
| --- a/string/test-strstr.c
 | ||||
| +++ b/string/test-strstr.c
 | ||||
| @@ -151,6 +151,32 @@ check2 (void)
 | ||||
|      } | ||||
|  } | ||||
|   | ||||
| +#define N 1024
 | ||||
| +
 | ||||
| +static void
 | ||||
| +pr23637 (void)
 | ||||
| +{
 | ||||
| +  char *h = (char*) buf1;
 | ||||
| +  char *n = (char*) buf2;
 | ||||
| +
 | ||||
| +  for (int i = 0; i < N; i++)
 | ||||
| +    {
 | ||||
| +      n[i] = 'x';
 | ||||
| +      h[i] = ' ';
 | ||||
| +      h[i + N] = 'x';
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  n[N] = '\0';
 | ||||
| +  h[N * 2] = '\0';
 | ||||
| +
 | ||||
| +  /* Ensure we don't match at the first 'x'.  */
 | ||||
| +  h[0] = 'x';
 | ||||
| +
 | ||||
| +  char *exp_result = stupid_strstr (h, n);
 | ||||
| +  FOR_EACH_IMPL (impl, 0)
 | ||||
| +    check_result (impl, h, n, exp_result);
 | ||||
| +}
 | ||||
| +
 | ||||
|  static int | ||||
|  test_main (void) | ||||
|  { | ||||
| @@ -158,6 +184,7 @@ test_main (void)
 | ||||
|   | ||||
|    check1 (); | ||||
|    check2 (); | ||||
| +  pr23637 ();
 | ||||
|   | ||||
|    printf ("%23s", ""); | ||||
|    FOR_EACH_IMPL (impl, 0) | ||||
| @@ -202,6 +229,9 @@ test_main (void)
 | ||||
|  	do_test (15, 9, hlen, klen, 1); | ||||
|  	do_test (15, 15, hlen, klen, 0); | ||||
|  	do_test (15, 15, hlen, klen, 1); | ||||
| +
 | ||||
| +	do_test (15, 15, hlen + klen * 4, klen * 4, 0);
 | ||||
| +	do_test (15, 15, hlen + klen * 4, klen * 4, 1);
 | ||||
|        } | ||||
|   | ||||
|    do_test (0, 0, page_size - 1, 16, 0); | ||||
							
								
								
									
										82
									
								
								SOURCES/glibc-rh1631730.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								SOURCES/glibc-rh1631730.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,82 @@ | ||||
| commit 2339d6a55eb7a7e040ae888e906adc49eeb59eab | ||||
| Author: H.J. Lu <hjl.tools@gmail.com> | ||||
| Date:   Wed Sep 12 08:40:59 2018 -0700 | ||||
| 
 | ||||
|     i386: Use ENTRY and END in start.S [BZ #23606] | ||||
|      | ||||
|     Wrapping the _start function with ENTRY and END to insert ENDBR32 at | ||||
|     function entry when CET is enabled.  Since _start now includes CFI, | ||||
|     without "cfi_undefined (eip)", unwinder may not terminate at _start | ||||
|     and we will get | ||||
|      | ||||
|     Program received signal SIGSEGV, Segmentation fault. | ||||
|     0xf7dc661e in ?? () from /lib/libgcc_s.so.1 | ||||
|     Missing separate debuginfos, use: dnf debuginfo-install libgcc-8.2.1-3.0.fc28.i686 | ||||
|     (gdb) bt | ||||
|      #0  0xf7dc661e in ?? () from /lib/libgcc_s.so.1 | ||||
|      #1  0xf7dc7c18 in _Unwind_Backtrace () from /lib/libgcc_s.so.1 | ||||
|      #2  0xf7f0d809 in __GI___backtrace (array=array@entry=0xffffc7d0, | ||||
|         size=size@entry=20) at ../sysdeps/i386/backtrace.c:127 | ||||
|      #3  0x08049254 in compare (p1=p1@entry=0xffffcad0, p2=p2@entry=0xffffcad4) | ||||
|         at backtrace-tst.c:12 | ||||
|      #4  0xf7e2a28c in msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, | ||||
|         n=n@entry=2) at msort.c:65 | ||||
|      #5  0xf7e29f64 in msort_with_tmp (n=2, b=0xffffcad0, p=0xffffca5c) | ||||
|         at msort.c:53 | ||||
|      #6  msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=5) | ||||
|         at msort.c:53 | ||||
|      #7  0xf7e29f64 in msort_with_tmp (n=5, b=0xffffcad0, p=0xffffca5c) | ||||
|         at msort.c:53 | ||||
|      #8  msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=10) | ||||
|         at msort.c:53 | ||||
|      #9  0xf7e29f64 in msort_with_tmp (n=10, b=0xffffcad0, p=0xffffca5c) | ||||
|         at msort.c:53 | ||||
|      #10 msort_with_tmp (p=p@entry=0xffffca5c, b=b@entry=0xffffcad0, n=n@entry=20) | ||||
|         at msort.c:53 | ||||
|      #11 0xf7e2a5b6 in msort_with_tmp (n=20, b=0xffffcad0, p=0xffffca5c) | ||||
|         at msort.c:297 | ||||
|      #12 __GI___qsort_r (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4, | ||||
|         cmp=cmp@entry=0x8049230 <compare>, arg=arg@entry=0x0) at msort.c:297 | ||||
|      #13 0xf7e2a84d in __GI_qsort (b=b@entry=0xffffcad0, n=n@entry=20, s=s@entry=4, | ||||
|         cmp=cmp@entry=0x8049230 <compare>) at msort.c:308 | ||||
|      #14 0x080490f6 in main (argc=2, argv=0xffffcbd4) at backtrace-tst.c:39 | ||||
|      | ||||
|     FAIL: debug/backtrace-tst | ||||
|      | ||||
|             [BZ #23606] | ||||
|             * sysdeps/i386/start.S: Include <sysdep.h> | ||||
|             (_start): Use ENTRY/END to insert ENDBR32 at entry when CET is | ||||
|             enabled.  Add cfi_undefined (eip). | ||||
|      | ||||
|     Signed-off-by: H.J. Lu <hjl.tools@gmail.com> | ||||
|      | ||||
|     (cherry picked from commit 5a274db4ea363d6b0b92933f085a92daaf1be2f2) | ||||
| 
 | ||||
| diff --git a/sysdeps/i386/start.S b/sysdeps/i386/start.S
 | ||||
| index 91035fa83fb7ee38..e35e9bd31b2cea30 100644
 | ||||
| --- a/sysdeps/i386/start.S
 | ||||
| +++ b/sysdeps/i386/start.S
 | ||||
| @@ -52,10 +52,11 @@
 | ||||
|  					NULL | ||||
|  */ | ||||
|   | ||||
| -	.text
 | ||||
| -	.globl _start
 | ||||
| -	.type _start,@function
 | ||||
| -_start:
 | ||||
| +#include <sysdep.h>
 | ||||
| +
 | ||||
| +ENTRY (_start)
 | ||||
| +	/* Clearing frame pointer is insufficient, use CFI.  */
 | ||||
| +	cfi_undefined (eip)
 | ||||
|  	/* Clear the frame pointer.  The ABI suggests this be done, to mark | ||||
|  	   the outermost frame obviously.  */ | ||||
|  	xorl %ebp, %ebp | ||||
| @@ -131,6 +132,7 @@ _start:
 | ||||
|  1:	movl	(%esp), %ebx | ||||
|  	ret | ||||
|  #endif | ||||
| +END (_start)
 | ||||
|   | ||||
|  /* To fulfill the System V/i386 ABI we need this symbol.  Yuck, it's so | ||||
|     meaningless since we don't support machines < 80386.  */ | ||||
							
								
								
									
										483
									
								
								SOURCES/glibc-rh1635779.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										483
									
								
								SOURCES/glibc-rh1635779.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,483 @@ | ||||
| commit e5d262effe3a87164308a3f37e61b32d0348692a | ||||
| Author: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | ||||
| Date:   Fri Nov 30 18:05:32 2018 -0200 | ||||
| 
 | ||||
|     Fix _dl_profile_fixup data-dependency issue (Bug 23690) | ||||
|      | ||||
|     There is a data-dependency between the fields of struct l_reloc_result | ||||
|     and the field used as the initialization guard. Users of the guard | ||||
|     expect writes to the structure to be observable when they also observe | ||||
|     the guard initialized. The solution for this problem is to use an acquire | ||||
|     and release load and store to ensure previous writes to the structure are | ||||
|     observable if the guard is initialized. | ||||
|      | ||||
|     The previous implementation used DL_FIXUP_VALUE_ADDR (l_reloc_result->addr) | ||||
|     as the initialization guard, making it impossible for some architectures | ||||
|     to load and store it atomically, i.e. hppa and ia64, due to its larger size. | ||||
|      | ||||
|     This commit adds an unsigned int to l_reloc_result to be used as the new | ||||
|     initialization guard of the struct, making it possible to load and store | ||||
|     it atomically in all architectures. The fix ensures that the values | ||||
|     observed in l_reloc_result are consistent and do not lead to crashes. | ||||
|     The algorithm is documented in the code in elf/dl-runtime.c | ||||
|     (_dl_profile_fixup). Not all data races have been eliminated. | ||||
|      | ||||
|     Tested with build-many-glibcs and on powerpc, powerpc64, and powerpc64le. | ||||
|      | ||||
|             [BZ #23690] | ||||
|             * elf/dl-runtime.c (_dl_profile_fixup): Guarantee memory | ||||
|             modification order when accessing reloc_result->addr. | ||||
|             * include/link.h (reloc_result): Add field init. | ||||
|             * nptl/Makefile (tests): Add tst-audit-threads. | ||||
|             (modules-names): Add tst-audit-threads-mod1 and | ||||
|             tst-audit-threads-mod2. | ||||
|             Add rules to build tst-audit-threads. | ||||
|             * nptl/tst-audit-threads-mod1.c: New file. | ||||
|             * nptl/tst-audit-threads-mod2.c: Likewise. | ||||
|             * nptl/tst-audit-threads.c: Likewise. | ||||
|             * nptl/tst-audit-threads.h: Likewise. | ||||
|      | ||||
|     Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
 | ||||
| index 63bbc89776..3d2f4a7a76 100644
 | ||||
| --- a/elf/dl-runtime.c
 | ||||
| +++ b/elf/dl-runtime.c
 | ||||
| @@ -183,10 +183,36 @@ _dl_profile_fixup (
 | ||||
|    /* This is the address in the array where we store the result of previous | ||||
|       relocations.  */ | ||||
|    struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index]; | ||||
| -  DL_FIXUP_VALUE_TYPE *resultp = &reloc_result->addr;
 | ||||
|   | ||||
| -  DL_FIXUP_VALUE_TYPE value = *resultp;
 | ||||
| -  if (DL_FIXUP_VALUE_CODE_ADDR (value) == 0)
 | ||||
| + /* CONCURRENCY NOTES:
 | ||||
| +
 | ||||
| +  Multiple threads may be calling the same PLT sequence and with
 | ||||
| +  LD_AUDIT enabled they will be calling into _dl_profile_fixup to
 | ||||
| +  update the reloc_result with the result of the lazy resolution.
 | ||||
| +  The reloc_result guard variable is reloc_init, and we use
 | ||||
| +  acquire/release loads and store to it to ensure that the results of
 | ||||
| +  the structure are consistent with the loaded value of the guard.
 | ||||
| +  This does not fix all of the data races that occur when two or more
 | ||||
| +  threads read reloc_result->reloc_init with a value of zero and read
 | ||||
| +  and write to that reloc_result concurrently.  The expectation is
 | ||||
| +  generally that while this is a data race it works because the
 | ||||
| +  threads write the same values.  Until the data races are fixed
 | ||||
| +  there is a potential for problems to arise from these data races.
 | ||||
| +  The reloc result updates should happen in parallel but there should
 | ||||
| +  be an atomic RMW which does the final update to the real result
 | ||||
| +  entry (see bug 23790).
 | ||||
| +
 | ||||
| +  The following code uses reloc_result->init set to 0 to indicate if it is
 | ||||
| +  the first time this object is being relocated, otherwise 1 which
 | ||||
| +  indicates the object has already been relocated.
 | ||||
| +
 | ||||
| +  Reading/Writing from/to reloc_result->reloc_init must not happen
 | ||||
| +  before previous writes to reloc_result complete as they could
 | ||||
| +  end-up with an incomplete struct.  */
 | ||||
| +  DL_FIXUP_VALUE_TYPE value;
 | ||||
| +  unsigned int init = atomic_load_acquire (&reloc_result->init);
 | ||||
| +
 | ||||
| +  if (init == 0)
 | ||||
|      { | ||||
|        /* This is the first time we have to relocate this object.  */ | ||||
|        const ElfW(Sym) *const symtab | ||||
| @@ -346,19 +372,31 @@ _dl_profile_fixup (
 | ||||
|   | ||||
|        /* Store the result for later runs.  */ | ||||
|        if (__glibc_likely (! GLRO(dl_bind_not))) | ||||
| -	*resultp = value;
 | ||||
| +	{
 | ||||
| +	  reloc_result->addr = value;
 | ||||
| +	  /* Guarantee all previous writes complete before
 | ||||
| +	     init is updated.  See CONCURRENCY NOTES earlier  */
 | ||||
| +	  atomic_store_release (&reloc_result->init, 1);
 | ||||
| +	}
 | ||||
| +      init = 1;
 | ||||
|      } | ||||
| +  else
 | ||||
| +    value = reloc_result->addr;
 | ||||
|   | ||||
|    /* By default we do not call the pltexit function.  */ | ||||
|    long int framesize = -1; | ||||
|   | ||||
| +
 | ||||
|  #ifdef SHARED | ||||
|    /* Auditing checkpoint: report the PLT entering and allow the | ||||
|       auditors to change the value.  */ | ||||
| -  if (DL_FIXUP_VALUE_CODE_ADDR (value) != 0 && GLRO(dl_naudit) > 0
 | ||||
| +  if (GLRO(dl_naudit) > 0
 | ||||
|        /* Don't do anything if no auditor wants to intercept this call.  */ | ||||
|        && (reloc_result->enterexit & LA_SYMB_NOPLTENTER) == 0) | ||||
|      { | ||||
| +      /* Sanity check:  DL_FIXUP_VALUE_CODE_ADDR (value) should have been
 | ||||
| +	 initialized earlier in this function or in another thread.  */
 | ||||
| +      assert (DL_FIXUP_VALUE_CODE_ADDR (value) != 0);
 | ||||
|        ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound, | ||||
|  						l_info[DT_SYMTAB]) | ||||
|  			   + reloc_result->boundndx); | ||||
| diff --git a/include/link.h b/include/link.h
 | ||||
| index 5924594548..83b1c34b7b 100644
 | ||||
| --- a/include/link.h
 | ||||
| +++ b/include/link.h
 | ||||
| @@ -216,6 +216,10 @@ struct link_map
 | ||||
|        unsigned int boundndx; | ||||
|        uint32_t enterexit; | ||||
|        unsigned int flags; | ||||
| +      /* CONCURRENCY NOTE: This is used to guard the concurrent initialization
 | ||||
| +	 of the relocation result across multiple threads.  See the more
 | ||||
| +	 detailed notes in elf/dl-runtime.c.  */
 | ||||
| +      unsigned int init;
 | ||||
|      } *l_reloc_result; | ||||
|   | ||||
|      /* Pointer to the version information if available.  */ | ||||
| diff --git a/nptl/Makefile b/nptl/Makefile
 | ||||
| index 982e43adfa..98b0aa01c7 100644
 | ||||
| --- a/nptl/Makefile
 | ||||
| +++ b/nptl/Makefile
 | ||||
| @@ -382,7 +382,8 @@ tests += tst-cancelx2 tst-cancelx3 tst-cancelx4 tst-cancelx5 \
 | ||||
|  	 tst-cleanupx0 tst-cleanupx1 tst-cleanupx2 tst-cleanupx3 tst-cleanupx4 \ | ||||
|  	 tst-oncex3 tst-oncex4 | ||||
|  ifeq ($(build-shared),yes) | ||||
| -tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder
 | ||||
| +tests += tst-atfork2 tst-tls4 tst-_res1 tst-fini1 tst-compat-forwarder \
 | ||||
| +	 tst-audit-threads
 | ||||
|  tests-internal += tst-tls3 tst-tls3-malloc tst-tls5 tst-stackguard1 | ||||
|  tests-nolibpthread += tst-fini1 | ||||
|  ifeq ($(have-z-execstack),yes) | ||||
| @@ -394,7 +395,8 @@ modules-names = tst-atfork2mod tst-tls3mod tst-tls4moda tst-tls4modb \
 | ||||
|  		tst-tls5mod tst-tls5moda tst-tls5modb tst-tls5modc \ | ||||
|  		tst-tls5modd tst-tls5mode tst-tls5modf tst-stack4mod \ | ||||
|  		tst-_res1mod1 tst-_res1mod2 tst-execstack-mod tst-fini1mod \ | ||||
| -		tst-join7mod tst-compat-forwarder-mod
 | ||||
| +		tst-join7mod tst-compat-forwarder-mod tst-audit-threads-mod1 \
 | ||||
| +		tst-audit-threads-mod2
 | ||||
|  extra-test-objs += $(addsuffix .os,$(strip $(modules-names))) \ | ||||
|  		   tst-cleanup4aux.o tst-cleanupx4aux.o | ||||
|  test-extras += tst-cleanup4aux tst-cleanupx4aux | ||||
| @@ -712,6 +714,14 @@ $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so
 | ||||
|   | ||||
|  tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1 | ||||
|   | ||||
| +# Protect against a build using -Wl,-z,now.
 | ||||
| +LDFLAGS-tst-audit-threads-mod1.so = -Wl,-z,lazy
 | ||||
| +LDFLAGS-tst-audit-threads-mod2.so = -Wl,-z,lazy
 | ||||
| +LDFLAGS-tst-audit-threads = -Wl,-z,lazy
 | ||||
| +$(objpfx)tst-audit-threads: $(objpfx)tst-audit-threads-mod2.so
 | ||||
| +$(objpfx)tst-audit-threads.out: $(objpfx)tst-audit-threads-mod1.so
 | ||||
| +tst-audit-threads-ENV = LD_AUDIT=$(objpfx)tst-audit-threads-mod1.so
 | ||||
| +
 | ||||
|  # The tests here better do not run in parallel | ||||
|  ifneq ($(filter %tests,$(MAKECMDGOALS)),) | ||||
|  .NOTPARALLEL: | ||||
| diff --git a/nptl/tst-audit-threads-mod1.c b/nptl/tst-audit-threads-mod1.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000..615d5ee512
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-audit-threads-mod1.c
 | ||||
| @@ -0,0 +1,74 @@
 | ||||
| +/* Dummy audit library for test-audit-threads.
 | ||||
| +
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <elf.h>
 | ||||
| +#include <link.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <assert.h>
 | ||||
| +#include <string.h>
 | ||||
| +
 | ||||
| +/* We must use a dummy LD_AUDIT module to force the dynamic loader to
 | ||||
| +   *not* update the real PLT, and instead use a cached value for the
 | ||||
| +   lazy resolution result.  It is the update of that cached value that
 | ||||
| +   we are testing for correctness by doing this.  */
 | ||||
| +
 | ||||
| +/* Library to be audited.  */
 | ||||
| +#define LIB "tst-audit-threads-mod2.so"
 | ||||
| +/* CALLNUM is the number of retNum functions.  */
 | ||||
| +#define CALLNUM 7999
 | ||||
| +
 | ||||
| +#define CONCATX(a, b) __CONCAT (a, b)
 | ||||
| +
 | ||||
| +static int previous = 0;
 | ||||
| +
 | ||||
| +unsigned int
 | ||||
| +la_version (unsigned int ver)
 | ||||
| +{
 | ||||
| +  return 1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +unsigned int
 | ||||
| +la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
 | ||||
| +{
 | ||||
| +  return LA_FLG_BINDTO | LA_FLG_BINDFROM;
 | ||||
| +}
 | ||||
| +
 | ||||
| +uintptr_t
 | ||||
| +CONCATX(la_symbind, __ELF_NATIVE_CLASS) (ElfW(Sym) *sym,
 | ||||
| +					unsigned int ndx,
 | ||||
| +					uintptr_t *refcook,
 | ||||
| +					uintptr_t *defcook,
 | ||||
| +					unsigned int *flags,
 | ||||
| +					const char *symname)
 | ||||
| +{
 | ||||
| +  const char * retnum = "retNum";
 | ||||
| +  char * num = strstr (symname, retnum);
 | ||||
| +  int n;
 | ||||
| +  /* Validate if the symbols are getting called in the correct order.
 | ||||
| +     This code is here to verify binutils does not optimize out the PLT
 | ||||
| +     entries that require the symbol binding.  */
 | ||||
| +  if (num != NULL)
 | ||||
| +    {
 | ||||
| +      n = atoi (num);
 | ||||
| +      assert (n >= previous);
 | ||||
| +      assert (n <= CALLNUM);
 | ||||
| +      previous = n;
 | ||||
| +    }
 | ||||
| +  return sym->st_value;
 | ||||
| +}
 | ||||
| diff --git a/nptl/tst-audit-threads-mod2.c b/nptl/tst-audit-threads-mod2.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000..f9817dd3dc
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-audit-threads-mod2.c
 | ||||
| @@ -0,0 +1,22 @@
 | ||||
| +/* Shared object with a huge number of functions for test-audit-threads.
 | ||||
| +
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* Define all the retNumN functions in a library.  */
 | ||||
| +#define definenum
 | ||||
| +#include "tst-audit-threads.h"
 | ||||
| diff --git a/nptl/tst-audit-threads.c b/nptl/tst-audit-threads.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000..e4bf433bd8
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-audit-threads.c
 | ||||
| @@ -0,0 +1,97 @@
 | ||||
| +/* Test multi-threading using LD_AUDIT.
 | ||||
| +
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* This test uses a dummy LD_AUDIT library (test-audit-threads-mod1) and a
 | ||||
| +   library with a huge number of functions in order to validate lazy symbol
 | ||||
| +   binding with an audit library.  We use one thread per CPU to test that
 | ||||
| +   concurrent lazy resolution does not have any defects which would cause
 | ||||
| +   the process to fail.  We use an LD_AUDIT library to force the testing of
 | ||||
| +   the relocation resolution caching code in the dynamic loader i.e.
 | ||||
| +   _dl_runtime_profile and _dl_profile_fixup.  */
 | ||||
| +
 | ||||
| +#include <support/xthread.h>
 | ||||
| +#include <strings.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <sys/sysinfo.h>
 | ||||
| +
 | ||||
| +static int do_test (void);
 | ||||
| +
 | ||||
| +/* This test usually takes less than 3s to run.  However, there are cases that
 | ||||
| +   take up to 30s.  */
 | ||||
| +#define TIMEOUT 60
 | ||||
| +#define TEST_FUNCTION do_test ()
 | ||||
| +#include "../test-skeleton.c"
 | ||||
| +
 | ||||
| +/* Declare the functions we are going to call.  */
 | ||||
| +#define externnum
 | ||||
| +#include "tst-audit-threads.h"
 | ||||
| +#undef externnum
 | ||||
| +
 | ||||
| +int num_threads;
 | ||||
| +pthread_barrier_t barrier;
 | ||||
| +
 | ||||
| +void
 | ||||
| +sync_all (int num)
 | ||||
| +{
 | ||||
| +  pthread_barrier_wait (&barrier);
 | ||||
| +}
 | ||||
| +
 | ||||
| +void
 | ||||
| +call_all_ret_nums (void)
 | ||||
| +{
 | ||||
| +  /* Call each function one at a time from all threads.  */
 | ||||
| +#define callnum
 | ||||
| +#include "tst-audit-threads.h"
 | ||||
| +#undef callnum
 | ||||
| +}
 | ||||
| +
 | ||||
| +void *
 | ||||
| +thread_main (void *unused)
 | ||||
| +{
 | ||||
| +  call_all_ret_nums ();
 | ||||
| +  return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define STR2(X) #X
 | ||||
| +#define STR(X) STR2(X)
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  int i;
 | ||||
| +  pthread_t *threads;
 | ||||
| +
 | ||||
| +  num_threads = get_nprocs ();
 | ||||
| +  if (num_threads <= 1)
 | ||||
| +    num_threads = 2;
 | ||||
| +
 | ||||
| +  /* Used to synchronize all the threads after calling each retNumN.  */
 | ||||
| +  xpthread_barrier_init (&barrier, NULL, num_threads);
 | ||||
| +
 | ||||
| +  threads = (pthread_t *) xcalloc (num_threads, sizeof(pthread_t));
 | ||||
| +  for (i = 0; i < num_threads; i++)
 | ||||
| +    threads[i] = xpthread_create(NULL, thread_main, NULL);
 | ||||
| +
 | ||||
| +  for (i = 0; i < num_threads; i++)
 | ||||
| +    xpthread_join(threads[i]);
 | ||||
| +
 | ||||
| +  free (threads);
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| diff --git a/nptl/tst-audit-threads.h b/nptl/tst-audit-threads.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000..1c9ecc08df
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-audit-threads.h
 | ||||
| @@ -0,0 +1,92 @@
 | ||||
| +/* Helper header for test-audit-threads.
 | ||||
| +
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* We use this helper to create a large number of functions, all of
 | ||||
| +   which will be resolved lazily and thus have their PLT updated.
 | ||||
| +   This is done to provide enough functions that we can statistically
 | ||||
| +   observe a thread vs. PLT resolution failure if one exists.  */
 | ||||
| +
 | ||||
| +#define CONCAT(a, b) a ## b
 | ||||
| +#define NUM(x, y) CONCAT (x, y)
 | ||||
| +
 | ||||
| +#define FUNC10(x)	\
 | ||||
| +  FUNC (NUM (x, 0));	\
 | ||||
| +  FUNC (NUM (x, 1));	\
 | ||||
| +  FUNC (NUM (x, 2));	\
 | ||||
| +  FUNC (NUM (x, 3));	\
 | ||||
| +  FUNC (NUM (x, 4));	\
 | ||||
| +  FUNC (NUM (x, 5));	\
 | ||||
| +  FUNC (NUM (x, 6));	\
 | ||||
| +  FUNC (NUM (x, 7));	\
 | ||||
| +  FUNC (NUM (x, 8));	\
 | ||||
| +  FUNC (NUM (x, 9))
 | ||||
| +
 | ||||
| +#define FUNC100(x)	\
 | ||||
| +  FUNC10 (NUM (x, 0));	\
 | ||||
| +  FUNC10 (NUM (x, 1));	\
 | ||||
| +  FUNC10 (NUM (x, 2));	\
 | ||||
| +  FUNC10 (NUM (x, 3));	\
 | ||||
| +  FUNC10 (NUM (x, 4));	\
 | ||||
| +  FUNC10 (NUM (x, 5));	\
 | ||||
| +  FUNC10 (NUM (x, 6));	\
 | ||||
| +  FUNC10 (NUM (x, 7));	\
 | ||||
| +  FUNC10 (NUM (x, 8));	\
 | ||||
| +  FUNC10 (NUM (x, 9))
 | ||||
| +
 | ||||
| +#define FUNC1000(x)		\
 | ||||
| +  FUNC100 (NUM (x, 0));		\
 | ||||
| +  FUNC100 (NUM (x, 1));		\
 | ||||
| +  FUNC100 (NUM (x, 2));		\
 | ||||
| +  FUNC100 (NUM (x, 3));		\
 | ||||
| +  FUNC100 (NUM (x, 4));		\
 | ||||
| +  FUNC100 (NUM (x, 5));		\
 | ||||
| +  FUNC100 (NUM (x, 6));		\
 | ||||
| +  FUNC100 (NUM (x, 7));		\
 | ||||
| +  FUNC100 (NUM (x, 8));		\
 | ||||
| +  FUNC100 (NUM (x, 9))
 | ||||
| +
 | ||||
| +#define FUNC7000()	\
 | ||||
| +  FUNC1000 (1);		\
 | ||||
| +  FUNC1000 (2);		\
 | ||||
| +  FUNC1000 (3);		\
 | ||||
| +  FUNC1000 (4);		\
 | ||||
| +  FUNC1000 (5);		\
 | ||||
| +  FUNC1000 (6);		\
 | ||||
| +  FUNC1000 (7);
 | ||||
| +
 | ||||
| +#ifdef FUNC
 | ||||
| +# undef FUNC
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef externnum
 | ||||
| +# define FUNC(x) extern int CONCAT (retNum, x) (void)
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef definenum
 | ||||
| +# define FUNC(x) int CONCAT (retNum, x) (void) { return x; }
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef callnum
 | ||||
| +# define FUNC(x) CONCAT (retNum, x) (); sync_all (x)
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +/* A value of 7000 functions is chosen as an arbitrarily large
 | ||||
| +   number of functions that will allow us enough attempts to
 | ||||
| +   verify lazy resolution operation.  */
 | ||||
| +FUNC7000 ();
 | ||||
							
								
								
									
										35
									
								
								SOURCES/glibc-rh1638520.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								SOURCES/glibc-rh1638520.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| commit ed643089cd3251038863d32e67ec47b94cd557f3 | ||||
| Author: Szabolcs Nagy <szabolcs.nagy@arm.com> | ||||
| Date:   Tue Oct 9 14:31:28 2018 +0100 | ||||
| 
 | ||||
|     Increase timeout of libio/tst-readline | ||||
|      | ||||
|     Increase timeout from the default 20s to 100s. This test makes close to | ||||
|     20 million syscalls with distribution: | ||||
|      | ||||
|     12327675 read | ||||
|      4143204 lseek | ||||
|       929475 close | ||||
|       929471 openat | ||||
|        92817 fstat | ||||
|         1431 write | ||||
|     ... | ||||
|      | ||||
|     The default timeout assumes each can finish in 1us on average which | ||||
|     is not true on slow machines. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
|      | ||||
|             * libio/tst-readline.c (TIMEOUT): Define. | ||||
| 
 | ||||
| diff --git a/libio/tst-readline.c b/libio/tst-readline.c
 | ||||
| index 9322ef68da5e38a9..63f5227760d88c63 100644
 | ||||
| --- a/libio/tst-readline.c
 | ||||
| +++ b/libio/tst-readline.c
 | ||||
| @@ -232,5 +232,6 @@ do_test (void)
 | ||||
|    return 0; | ||||
|  } | ||||
|   | ||||
| +#define TIMEOUT 100
 | ||||
|  #define PREPARE prepare | ||||
|  #include <support/test-driver.c> | ||||
							
								
								
									
										2823
									
								
								SOURCES/glibc-rh1638523-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2823
									
								
								SOURCES/glibc-rh1638523-1.patch
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										80
									
								
								SOURCES/glibc-rh1638523-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										80
									
								
								SOURCES/glibc-rh1638523-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,80 @@ | ||||
| commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523 | ||||
| Author: Paul Pluzhnikov <ppluzhnikov@kazbek.mtv.corp.google.com> | ||||
| Date:   Fri Aug 24 18:08:51 2018 -0700 | ||||
| 
 | ||||
|     Fix BZ#23400 (creating temporary files in source tree), and undefined behavior in test. | ||||
| 
 | ||||
| diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
 | ||||
| index e7837f98c19fc4bf..d1aa69106ccf6ac5 100644
 | ||||
| --- a/stdlib/test-bz22786.c
 | ||||
| +++ b/stdlib/test-bz22786.c
 | ||||
| @@ -26,28 +26,20 @@
 | ||||
|  #include <unistd.h> | ||||
|  #include <sys/stat.h> | ||||
|  #include <sys/types.h> | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/temp_file.h>
 | ||||
|  #include <support/test-driver.h> | ||||
|  #include <libc-diag.h> | ||||
|   | ||||
|  static int | ||||
|  do_test (void) | ||||
|  { | ||||
| -  const char dir[] = "bz22786";
 | ||||
| -  const char lnk[] = "bz22786/symlink";
 | ||||
| +  const char *dir = support_create_temp_directory ("bz22786.");
 | ||||
| +  const char *lnk = xasprintf ("%s/symlink", dir);
 | ||||
| +  const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1;
 | ||||
|   | ||||
| -  rmdir (dir);
 | ||||
| -  if (mkdir (dir, 0755) != 0 && errno != EEXIST)
 | ||||
| -    {
 | ||||
| -      printf ("mkdir %s: %m\n", dir);
 | ||||
| -      return EXIT_FAILURE;
 | ||||
| -    }
 | ||||
| -  if (symlink (".", lnk) != 0 && errno != EEXIST)
 | ||||
| -    {
 | ||||
| -      printf ("symlink (%s, %s): %m\n", dir, lnk);
 | ||||
| -      return EXIT_FAILURE;
 | ||||
| -    }
 | ||||
| -
 | ||||
| -  const size_t path_len = (size_t) INT_MAX + 1;
 | ||||
| +  TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
 | ||||
|   | ||||
|    DIAG_PUSH_NEEDS_COMMENT; | ||||
|  #if __GNUC_PREREQ (7, 0) | ||||
| @@ -55,20 +47,14 @@ do_test (void)
 | ||||
|       allocation to succeed for the test to work.  */ | ||||
|    DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); | ||||
|  #endif | ||||
| -  char *path = malloc (path_len);
 | ||||
| +  char *path = xmalloc (path_len);
 | ||||
|    DIAG_POP_NEEDS_COMMENT; | ||||
|   | ||||
| -  if (path == NULL)
 | ||||
| -    {
 | ||||
| -      printf ("malloc (%zu): %m\n", path_len);
 | ||||
| -      return EXIT_UNSUPPORTED;
 | ||||
| -    }
 | ||||
| -
 | ||||
| -  /* Construct very long path = "bz22786/symlink/aaaa....."  */
 | ||||
| -  char *p = mempcpy (path, lnk, sizeof (lnk) - 1);
 | ||||
| +  /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....."  */
 | ||||
| +  char *p = mempcpy (path, lnk, strlen (lnk));
 | ||||
|    *(p++) = '/'; | ||||
| -  memset (p, 'a', path_len - (path - p) - 2);
 | ||||
| -  p[path_len - (path - p) - 1] = '\0';
 | ||||
| +  memset (p, 'a', path_len - (p - path) - 2);
 | ||||
| +  p[path_len - (p - path) - 1] = '\0';
 | ||||
|   | ||||
|    /* This call crashes before the fix for bz22786 on 32-bit platforms.  */ | ||||
|    p = realpath (path, NULL); | ||||
| @@ -81,7 +67,6 @@ do_test (void)
 | ||||
|   | ||||
|    /* Cleanup.  */ | ||||
|    unlink (lnk); | ||||
| -  rmdir (dir);
 | ||||
|   | ||||
|    return 0; | ||||
|  } | ||||
							
								
								
									
										55
									
								
								SOURCES/glibc-rh1638523-3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								SOURCES/glibc-rh1638523-3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,55 @@ | ||||
| commit 3bad2358d67d371497079bba4f8eca9c0096f4e2 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Thu Aug 30 08:44:32 2018 +0200 | ||||
| 
 | ||||
|     Test stdlib/test-bz22786 exits now with unsupported if malloc fails. | ||||
|      | ||||
|     The test tries to allocate more than 2^31 bytes which will always fail on s390 | ||||
|     as it has maximum 2^31bit of memory. | ||||
|     Before commit 6c3a8a9d868a8deddf0d6dcc785b6d120de90523, this test returned | ||||
|     unsupported if malloc fails.  This patch re enables this behaviour. | ||||
|      | ||||
|     Furthermore support_delete_temp_files() failed to remove the temp directory | ||||
|     in this case as it is not empty due to the created symlink. | ||||
|     Thus the creation of the symlink is moved behind malloc. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * stdlib/test-bz22786.c (do_test): Return EXIT_UNSUPPORTED | ||||
|             if malloc fails. | ||||
| 
 | ||||
| diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
 | ||||
| index d1aa69106ccf6ac5..777bf9180f4b5022 100644
 | ||||
| --- a/stdlib/test-bz22786.c
 | ||||
| +++ b/stdlib/test-bz22786.c
 | ||||
| @@ -39,16 +39,25 @@ do_test (void)
 | ||||
|    const char *lnk = xasprintf ("%s/symlink", dir); | ||||
|    const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; | ||||
|   | ||||
| -  TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
 | ||||
| -
 | ||||
|    DIAG_PUSH_NEEDS_COMMENT; | ||||
|  #if __GNUC_PREREQ (7, 0) | ||||
|    /* GCC 7 warns about too-large allocations; here we need such | ||||
|       allocation to succeed for the test to work.  */ | ||||
|    DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than="); | ||||
|  #endif | ||||
| -  char *path = xmalloc (path_len);
 | ||||
| +  char *path = malloc (path_len);
 | ||||
|    DIAG_POP_NEEDS_COMMENT; | ||||
| +  if (path == NULL)
 | ||||
| +    {
 | ||||
| +      printf ("malloc (%zu): %m\n", path_len);
 | ||||
| +      /* On 31-bit s390 the malloc will always fail as we do not have
 | ||||
| +	 so much memory, and we want to mark the test unsupported.
 | ||||
| +	 Likewise on systems with little physical memory the test will
 | ||||
| +	 fail and should be unsupported.  */
 | ||||
| +      return EXIT_UNSUPPORTED;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  TEST_VERIFY_EXIT (symlink (".", lnk) == 0);
 | ||||
|   | ||||
|    /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....."  */ | ||||
|    char *p = mempcpy (path, lnk, strlen (lnk)); | ||||
							
								
								
									
										65
									
								
								SOURCES/glibc-rh1638523-4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								SOURCES/glibc-rh1638523-4.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| commit f5e7e95921847bd83186bfe621fc2b48c4de5477 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Oct 30 13:11:47 2018 +0100 | ||||
| 
 | ||||
|     stdlib/test-bz22786: Avoid spurious test failures using alias mappings | ||||
|      | ||||
|     On systems without enough random-access memory, stdlib/test-bz22786 | ||||
|     will go deeply into swap and time out, even with a substantial | ||||
|     TIMEOUTFACTOR.  This commit adds a facility to construct repeating | ||||
|     strings with alias mappings, so that the requirement for physical | ||||
|     memory, and uses it in stdlib/test-bz22786. | ||||
| 
 | ||||
| Adjusted here for conflicts due to the previous support/ backport in | ||||
| glibc-rh1638523-1.patch. | ||||
| 
 | ||||
| diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
 | ||||
| index 777bf9180f4b5022..bb1e04f2debe9042 100644
 | ||||
| --- a/stdlib/test-bz22786.c
 | ||||
| +++ b/stdlib/test-bz22786.c
 | ||||
| @@ -26,6 +26,7 @@
 | ||||
|  #include <unistd.h> | ||||
|  #include <sys/stat.h> | ||||
|  #include <sys/types.h> | ||||
| +#include <support/blob_repeat.h>
 | ||||
|  #include <support/check.h> | ||||
|  #include <support/support.h> | ||||
|  #include <support/temp_file.h> | ||||
| @@ -39,17 +40,12 @@ do_test (void)
 | ||||
|    const char *lnk = xasprintf ("%s/symlink", dir); | ||||
|    const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; | ||||
|   | ||||
| -  DIAG_PUSH_NEEDS_COMMENT;
 | ||||
| -#if __GNUC_PREREQ (7, 0)
 | ||||
| -  /* GCC 7 warns about too-large allocations; here we need such
 | ||||
| -     allocation to succeed for the test to work.  */
 | ||||
| -  DIAG_IGNORE_NEEDS_COMMENT (7, "-Walloc-size-larger-than=");
 | ||||
| -#endif
 | ||||
| -  char *path = malloc (path_len);
 | ||||
| -  DIAG_POP_NEEDS_COMMENT;
 | ||||
| +  struct support_blob_repeat repeat
 | ||||
| +    = support_blob_repeat_allocate ("a", 1, path_len);
 | ||||
| +  char *path = repeat.start;
 | ||||
|    if (path == NULL) | ||||
|      { | ||||
| -      printf ("malloc (%zu): %m\n", path_len);
 | ||||
| +      printf ("Repeated allocation (%zu bytes): %m\n", path_len);
 | ||||
|        /* On 31-bit s390 the malloc will always fail as we do not have | ||||
|  	 so much memory, and we want to mark the test unsupported. | ||||
|  	 Likewise on systems with little physical memory the test will | ||||
| @@ -62,7 +58,6 @@ do_test (void)
 | ||||
|    /* Construct very long path = "/tmp/bz22786.XXXX/symlink/aaaa....."  */ | ||||
|    char *p = mempcpy (path, lnk, strlen (lnk)); | ||||
|    *(p++) = '/'; | ||||
| -  memset (p, 'a', path_len - (p - path) - 2);
 | ||||
|    p[path_len - (p - path) - 1] = '\0'; | ||||
|   | ||||
|    /* This call crashes before the fix for bz22786 on 32-bit platforms.  */ | ||||
| @@ -76,6 +71,7 @@ do_test (void)
 | ||||
|   | ||||
|    /* Cleanup.  */ | ||||
|    unlink (lnk); | ||||
| +  support_blob_repeat_free (&repeat);
 | ||||
|   | ||||
|    return 0; | ||||
|  } | ||||
							
								
								
									
										51
									
								
								SOURCES/glibc-rh1638523-5.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								SOURCES/glibc-rh1638523-5.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,51 @@ | ||||
| commit 07da99aad93c9364acb7efdab47c27ba698f6313 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Oct 30 13:55:01 2018 +0100 | ||||
| 
 | ||||
|     stdlib/tst-strtod-overflow: Switch to support_blob_repeat | ||||
|      | ||||
|     This is another test with an avoidable large memory allocation. | ||||
| 
 | ||||
| diff --git a/stdlib/tst-strtod-overflow.c b/stdlib/tst-strtod-overflow.c
 | ||||
| index d14638d68ef4f471..dc53c1e521443e1d 100644
 | ||||
| --- a/stdlib/tst-strtod-overflow.c
 | ||||
| +++ b/stdlib/tst-strtod-overflow.c
 | ||||
| @@ -19,6 +19,8 @@
 | ||||
|  #include <stdio.h> | ||||
|  #include <stdlib.h> | ||||
|  #include <string.h> | ||||
| +#include <support/blob_repeat.h>
 | ||||
| +#include <support/test-driver.h>
 | ||||
|   | ||||
|  #define EXPONENT "e-2147483649" | ||||
|  #define SIZE 214748364 | ||||
| @@ -26,21 +28,23 @@
 | ||||
|  static int | ||||
|  do_test (void) | ||||
|  { | ||||
| -  char *p = malloc (1 + SIZE + sizeof (EXPONENT));
 | ||||
| -  if (p == NULL)
 | ||||
| +  struct support_blob_repeat repeat = support_blob_repeat_allocate
 | ||||
| +    ("0", 1, 1 + SIZE + sizeof (EXPONENT));
 | ||||
| +  if (repeat.size == 0)
 | ||||
|      { | ||||
| -      puts ("malloc failed, cannot test for overflow");
 | ||||
| -      return 0;
 | ||||
| +      puts ("warning: memory allocation failed, cannot test for overflow");
 | ||||
| +      return EXIT_UNSUPPORTED;
 | ||||
|      } | ||||
| +  char *p = repeat.start;
 | ||||
|    p[0] = '1'; | ||||
| -  memset (p + 1, '0', SIZE);
 | ||||
|    memcpy (p + 1 + SIZE, EXPONENT, sizeof (EXPONENT)); | ||||
|    double d = strtod (p, NULL); | ||||
|    if (d != 0) | ||||
|      { | ||||
| -      printf ("strtod returned wrong value: %a\n", d);
 | ||||
| +      printf ("error: strtod returned wrong value: %a\n", d);
 | ||||
|        return 1; | ||||
|      } | ||||
| +  support_blob_repeat_free (&repeat);
 | ||||
|    return 0; | ||||
|  } | ||||
|   | ||||
							
								
								
									
										30
									
								
								SOURCES/glibc-rh1638523-6.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								SOURCES/glibc-rh1638523-6.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| commit 60708030536df82616c16aa2f14f533c4362b969 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Oct 30 13:56:40 2018 +0100 | ||||
| 
 | ||||
|     stdlib/test-bz22786: Avoid memory leaks in the test itself | ||||
| 
 | ||||
| diff --git a/stdlib/test-bz22786.c b/stdlib/test-bz22786.c
 | ||||
| index bb1e04f2debe9042..8035e8a394e7d034 100644
 | ||||
| --- a/stdlib/test-bz22786.c
 | ||||
| +++ b/stdlib/test-bz22786.c
 | ||||
| @@ -36,8 +36,8 @@
 | ||||
|  static int | ||||
|  do_test (void) | ||||
|  { | ||||
| -  const char *dir = support_create_temp_directory ("bz22786.");
 | ||||
| -  const char *lnk = xasprintf ("%s/symlink", dir);
 | ||||
| +  char *dir = support_create_temp_directory ("bz22786.");
 | ||||
| +  char *lnk = xasprintf ("%s/symlink", dir);
 | ||||
|    const size_t path_len = (size_t) INT_MAX + strlen (lnk) + 1; | ||||
|   | ||||
|    struct support_blob_repeat repeat | ||||
| @@ -72,6 +72,8 @@ do_test (void)
 | ||||
|    /* Cleanup.  */ | ||||
|    unlink (lnk); | ||||
|    support_blob_repeat_free (&repeat); | ||||
| +  free (lnk);
 | ||||
| +  free (dir);
 | ||||
|   | ||||
|    return 0; | ||||
|  } | ||||
							
								
								
									
										35
									
								
								SOURCES/glibc-rh1639343-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								SOURCES/glibc-rh1639343-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| commit f9b645b4b0a10c43753296ce3fa40053fa44606a | ||||
| Author: Mike Frysinger <vapier@gentoo.org> | ||||
| Date:   Wed Apr 24 13:32:22 2019 +0200 | ||||
| 
 | ||||
|     memusagestat: use local glibc when linking [BZ #18465] | ||||
|      | ||||
|     The memusagestat is the only binary that has its own link line which | ||||
|     causes it to be linked against the existing installed C library.  It | ||||
|     has been this way since it was originally committed in 1999, but I | ||||
|     don't see any reason as to why.  Since we want all the programs we | ||||
|     build locally to be against the new copy of glibc, change the build | ||||
|     to be like all other programs. | ||||
| 
 | ||||
| diff --git a/malloc/Makefile b/malloc/Makefile
 | ||||
| index 388cf7e9ee3a2569..228a1279a5960d8c 100644
 | ||||
| --- a/malloc/Makefile
 | ||||
| +++ b/malloc/Makefile
 | ||||
| @@ -131,6 +131,7 @@ ifneq ($(cross-compiling),yes)
 | ||||
|  # If the gd library is available we build the `memusagestat' program. | ||||
|  ifneq ($(LIBGD),no) | ||||
|  others: $(objpfx)memusage | ||||
| +others += memusagestat
 | ||||
|  install-bin = memusagestat | ||||
|  install-bin-script += memusage | ||||
|  generated += memusagestat memusage | ||||
| @@ -154,8 +155,7 @@ cpp-srcs-left := $(memusagestat-modules)
 | ||||
|  lib := memusagestat | ||||
|  include $(patsubst %,$(..)libof-iterator.mk,$(cpp-srcs-left)) | ||||
|   | ||||
| -$(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
 | ||||
| -	$(LINK.o) -o $@ $^ $(libgd-LDFLAGS) -lgd -lpng -lz -lm
 | ||||
| +LDLIBS-memusagestat = $(libgd-LDFLAGS) -lgd -lpng -lz -lm
 | ||||
|   | ||||
|  ifeq ($(run-built-tests),yes) | ||||
|  ifeq (yes,$(build-shared)) | ||||
							
								
								
									
										90
									
								
								SOURCES/glibc-rh1639343-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								SOURCES/glibc-rh1639343-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,90 @@ | ||||
| commit 94a4e9e4f401ffe829a992820439977ead0a0ce7 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Thu Apr 25 10:41:43 2019 +0200 | ||||
| 
 | ||||
|     Extend BIND_NOW to installed programs with --enable-bind-now | ||||
|      | ||||
|     Commit 2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix | ||||
|     --enable-bind-now [BZ #21015]") extended BIND_NOW to all installed | ||||
|     shared objects.  This change also covers installed programs. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| diff --git a/INSTALL b/INSTALL
 | ||||
| index d6c8e899fbb47dac..d56e102ec9ed3281 100644
 | ||||
| --- a/INSTALL
 | ||||
| +++ b/INSTALL
 | ||||
| @@ -169,10 +169,10 @@ if 'CFLAGS' is specified it must enable optimization.  For example:
 | ||||
|       protection. | ||||
|   | ||||
|  '--enable-bind-now' | ||||
| -     Disable lazy binding for installed shared objects.  This provides
 | ||||
| -     additional security hardening because it enables full RELRO and a
 | ||||
| -     read-only global offset table (GOT), at the cost of slightly
 | ||||
| -     increased program load times.
 | ||||
| +     Disable lazy binding for installed shared objects and programs.
 | ||||
| +     This provides additional security hardening because it enables full
 | ||||
| +     RELRO and a read-only global offset table (GOT), at the cost of
 | ||||
| +     slightly increased program load times.
 | ||||
|   | ||||
|  '--enable-pt_chown' | ||||
|       The file 'pt_chown' is a helper binary for 'grantpt' (*note | ||||
| diff --git a/Makeconfig b/Makeconfig
 | ||||
| index 8dc2fec9dc683416..742c0c0783a14bfa 100644
 | ||||
| --- a/Makeconfig
 | ||||
| +++ b/Makeconfig
 | ||||
| @@ -398,6 +398,8 @@ endif
 | ||||
|  # test modules. | ||||
|  ifeq ($(bind-now),yes) | ||||
|  LDFLAGS-lib.so += -Wl,-z,now | ||||
| +# Extra flags for dynamically linked non-test main programs.
 | ||||
| +link-extra-flags += -Wl,-z,now
 | ||||
|  endif | ||||
|   | ||||
|  # Command to run after every final link (executable or shared object). | ||||
| @@ -426,7 +428,7 @@ ifndef +link-pie
 | ||||
|  	     $(link-extra-libs) | ||||
|  +link-pie-after-libc = $(+postctorS) $(+postinit) | ||||
|  define +link-pie | ||||
| -$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-pie-after-libc)
 | ||||
| +$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-pie-tests | ||||
| @@ -454,7 +456,7 @@ ifndef +link-static
 | ||||
|  	      $(link-extra-libs-static) | ||||
|  +link-static-after-libc = $(+postctorT) $(+postinit) | ||||
|  define +link-static | ||||
| -$(+link-static-before-libc) $(link-libc-static) $(+link-static-after-libc)
 | ||||
| +$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-static-tests | ||||
| @@ -485,7 +487,7 @@ else  # not build-pie-default
 | ||||
|  	      $(link-extra-libs) | ||||
|  +link-after-libc = $(+postctor) $(+postinit) | ||||
|  define +link | ||||
| -$(+link-before-libc) $(rtld-LDFLAGS) $(link-libc) $(+link-after-libc)
 | ||||
| +$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-tests | ||||
| diff --git a/manual/install.texi b/manual/install.texi
 | ||||
| index e757891dc2eebb2e..351d67c68b255f62 100644
 | ||||
| --- a/manual/install.texi
 | ||||
| +++ b/manual/install.texi
 | ||||
| @@ -199,10 +199,10 @@ number of routines called directly from assembler are excluded from this
 | ||||
|  protection. | ||||
|   | ||||
|  @item --enable-bind-now | ||||
| -Disable lazy binding for installed shared objects.  This provides
 | ||||
| -additional security hardening because it enables full RELRO and a
 | ||||
| -read-only global offset table (GOT), at the cost of slightly increased
 | ||||
| -program load times.
 | ||||
| +Disable lazy binding for installed shared objects and programs.  This
 | ||||
| +provides additional security hardening because it enables full RELRO
 | ||||
| +and a read-only global offset table (GOT), at the cost of slightly
 | ||||
| +increased program load times.
 | ||||
|   | ||||
|  @pindex pt_chown | ||||
|  @findex grantpt | ||||
							
								
								
									
										43
									
								
								SOURCES/glibc-rh1639343-3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								SOURCES/glibc-rh1639343-3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| commit b5ffdc48c20ae865b197b67e5a9068a528fbc198 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Thu Apr 25 10:41:52 2019 +0200 | ||||
| 
 | ||||
|     benchtests: Enable BIND_NOW if configured with --enable-bind-now | ||||
|      | ||||
|     Benchmarks should reflect distribution build policies, so it makes | ||||
|     sense to honor the BIND_NOW configuration for them. | ||||
|      | ||||
|     This commit keeps using $(+link-tests), so that the benchmarks are | ||||
|     linked according to the --enable-hardcoded-path-in-tests configure | ||||
|     option. | ||||
|      | ||||
|     Reviewed-by: Carlos O'Donell <carlos@redhat.com> | ||||
| 
 | ||||
| diff --git a/benchtests/Makefile b/benchtests/Makefile
 | ||||
| index bcd6a9c26d9a0005..28d6b0c43f5bd390 100644
 | ||||
| --- a/benchtests/Makefile
 | ||||
| +++ b/benchtests/Makefile
 | ||||
| @@ -235,13 +235,21 @@ bench-func: $(binaries-bench)
 | ||||
|  	  scripts/benchout.schema.json; \ | ||||
|  	fi | ||||
|   | ||||
| -$(timing-type) $(binaries-bench) $(binaries-benchset) \
 | ||||
| -	$(binaries-bench-malloc): %: %.o $(objpfx)json-lib.o \
 | ||||
| +ifeq ($(bind-now),yes)
 | ||||
| +link-bench-bind-now = -Wl,-z,now
 | ||||
| +endif
 | ||||
| +
 | ||||
| +bench-link-targets = $(timing-type) $(binaries-bench) $(binaries-benchset) \
 | ||||
| +	$(binaries-bench-malloc)
 | ||||
| +
 | ||||
| +$(bench-link-targets): %: %.o $(objpfx)json-lib.o \
 | ||||
|  	$(link-extra-libs-tests) \ | ||||
|    $(sort $(filter $(common-objpfx)lib%,$(link-libc))) \ | ||||
|    $(addprefix $(csu-objpfx),start.o) $(+preinit) $(+postinit) | ||||
|  	$(+link-tests) | ||||
|   | ||||
| +$(bench-link-targets): LDFLAGS += $(link-bench-bind-now)
 | ||||
| +
 | ||||
|  $(objpfx)bench-%.c: %-inputs $(bench-deps) | ||||
|  	{ if [ -n "$($*-INCLUDE)" ]; then \ | ||||
|  	  cat $($*-INCLUDE); \ | ||||
							
								
								
									
										100
									
								
								SOURCES/glibc-rh1639343-4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								SOURCES/glibc-rh1639343-4.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,100 @@ | ||||
| commit e30fb31c0ad8d31babd1d0d0f05e37c6579a870b | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Fri Apr 26 07:16:47 2019 +0200 | ||||
| 
 | ||||
|     Makeconfig: Move $(CC) to +link command variables | ||||
|      | ||||
|     This change is needed to add linker flags which come very early in the | ||||
|     command linke (before LDFLAGS) and are not applied to test programs | ||||
|     (only to installed programs). | ||||
| 
 | ||||
| diff --git a/Makeconfig b/Makeconfig
 | ||||
| index 742c0c0783a14bfa..1ad25fc5a7251aea 100644
 | ||||
| --- a/Makeconfig
 | ||||
| +++ b/Makeconfig
 | ||||
| @@ -415,7 +415,7 @@ link-extra-libs-tests = $(libsupport)
 | ||||
|   | ||||
|  # Command for linking PIE programs with the C library. | ||||
|  ifndef +link-pie | ||||
| -+link-pie-before-libc = $(CC) $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
 | ||||
| ++link-pie-before-libc = $(if $($(@F)-no-pie),$(no-pie-ldflag),-pie) \
 | ||||
|  	     -Wl,-O1 -nostdlib -nostartfiles -o $@ \ | ||||
|  	     $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ | ||||
|  	     $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ | ||||
| @@ -428,23 +428,24 @@ ifndef +link-pie
 | ||||
|  	     $(link-extra-libs) | ||||
|  +link-pie-after-libc = $(+postctorS) $(+postinit) | ||||
|  define +link-pie | ||||
| -$(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
 | ||||
| +$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \
 | ||||
| +  $(link-libc) $(+link-pie-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-pie-tests | ||||
| -$(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
 | ||||
| -			 $(+link-pie-after-libc)
 | ||||
| +$(CC) $(+link-pie-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
 | ||||
| +  $(+link-pie-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-pie-printers-tests | ||||
| -$(+link-pie-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \
 | ||||
| -			 $(+link-pie-after-libc)
 | ||||
| +$(CC) $(+link-pie-before-libc) $(built-rtld-LDFLAGS) \
 | ||||
| +  $(link-libc-printers-tests) $(+link-pie-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  endif | ||||
|  # Command for statically linking programs with the C library. | ||||
|  ifndef +link-static | ||||
| -+link-static-before-libc = $(CC) -nostdlib -nostartfiles -static -o $@ \
 | ||||
| ++link-static-before-libc = -nostdlib -nostartfiles -static -o $@ \
 | ||||
|  	      $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)) \ | ||||
|  	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F))  \ | ||||
|  	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(real-static-start-installed-name)) \ | ||||
| @@ -456,11 +457,13 @@ ifndef +link-static
 | ||||
|  	      $(link-extra-libs-static) | ||||
|  +link-static-after-libc = $(+postctorT) $(+postinit) | ||||
|  define +link-static | ||||
| -$(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) $(+link-static-after-libc)
 | ||||
| +$(CC) $(+link-static-before-libc) $(link-extra-flags) $(link-libc-static) \
 | ||||
| +  $(+link-static-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-static-tests | ||||
| -$(+link-static-before-libc) $(link-libc-static-tests) $(+link-static-after-libc)
 | ||||
| +$(CC) $(+link-static-before-libc) $(link-libc-static-tests) \
 | ||||
| +  $(+link-static-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  endif | ||||
| @@ -475,7 +478,7 @@ ifeq (yes,$(build-pie-default))
 | ||||
|  +link-tests = $(+link-pie-tests) | ||||
|  +link-printers-tests = $(+link-pie-printers-tests) | ||||
|  else  # not build-pie-default | ||||
| -+link-before-libc = $(CC) -nostdlib -nostartfiles -o $@ \
 | ||||
| ++link-before-libc = -nostdlib -nostartfiles -o $@ \
 | ||||
|  	      $(sysdep-LDFLAGS) $(LDFLAGS) $(LDFLAGS-$(@F)) \ | ||||
|  	      $(combreloc-LDFLAGS) $(relro-LDFLAGS) $(hashstyle-LDFLAGS) \ | ||||
|  	      $(firstword $(CRT-$(@F)) $(csu-objpfx)$(start-installed-name)) \ | ||||
| @@ -487,16 +490,17 @@ else  # not build-pie-default
 | ||||
|  	      $(link-extra-libs) | ||||
|  +link-after-libc = $(+postctor) $(+postinit) | ||||
|  define +link | ||||
| -$(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) $(+link-after-libc)
 | ||||
| +$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \
 | ||||
| +  $(+link-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-tests | ||||
| -$(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
 | ||||
| +$(CC) $(+link-before-libc) $(rtld-tests-LDFLAGS) $(link-libc-tests) \
 | ||||
|  		     $(+link-after-libc) | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-printers-tests | ||||
| -$(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \
 | ||||
| +$(CC) $(+link-before-libc) $(built-rtld-LDFLAGS) $(link-libc-printers-tests) \
 | ||||
|  		     $(+link-after-libc) | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
							
								
								
									
										74
									
								
								SOURCES/glibc-rh1639343-5.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								SOURCES/glibc-rh1639343-5.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,74 @@ | ||||
| commit a8ff215e56050a907189e713fd449bcafe99ff6b | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Fri Apr 26 07:16:30 2019 +0200 | ||||
| 
 | ||||
|     Makeconfig: Move -Wl,-rpath-link options before library references | ||||
|      | ||||
|     Previously, the -Wl,-rpath-link options came after the libraries | ||||
|     injected using LDLIBS-* variables on the link editor command line for | ||||
|     main programs.  As a result, it could happen that installed libraries | ||||
|     that reference glibc libraries used the installed glibc from the system | ||||
|     directories, instead of the glibc from the build tree.  This can lead to | ||||
|     link failures if the wrong version of libpthread.so.0 is used, for | ||||
|     instance, due to differences in the internal GLIBC_PRIVATE interfaces, | ||||
|     as seen with memusagestat and -lgd after commit | ||||
|     f9b645b4b0a10c43753296ce3fa40053fa44606a ("memusagestat: use local glibc | ||||
|     when linking [BZ #18465]"). | ||||
|      | ||||
|     The isolation is necessarily imperfect because these installed | ||||
|     libraries are linked against the installed glibc in the system | ||||
|     directories.  However, in most cases, the built glibc will be newer | ||||
|     than the installed glibc, and this link is permitted because of the | ||||
|     ABI backwards compatibility glibc provides. | ||||
| 
 | ||||
| diff --git a/Makeconfig b/Makeconfig
 | ||||
| index 1ad25fc5a7251aea..e315fb8a75ca5063 100644
 | ||||
| --- a/Makeconfig
 | ||||
| +++ b/Makeconfig
 | ||||
| @@ -428,8 +428,8 @@ ifndef +link-pie
 | ||||
|  	     $(link-extra-libs) | ||||
|  +link-pie-after-libc = $(+postctorS) $(+postinit) | ||||
|  define +link-pie | ||||
| -$(CC) $(+link-pie-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) \
 | ||||
| -  $(link-libc) $(+link-pie-after-libc)
 | ||||
| +$(CC) $(link-libc-rpath-link) $(+link-pie-before-libc) $(rtld-LDFLAGS) \
 | ||||
| +  $(link-extra-flags) $(link-libc) $(+link-pie-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-pie-tests | ||||
| @@ -490,8 +490,8 @@ else  # not build-pie-default
 | ||||
|  	      $(link-extra-libs) | ||||
|  +link-after-libc = $(+postctor) $(+postinit) | ||||
|  define +link | ||||
| -$(CC) $(+link-before-libc) $(rtld-LDFLAGS) $(link-extra-flags) $(link-libc) \
 | ||||
| -  $(+link-after-libc)
 | ||||
| +$(CC) $(link-libc-rpath-link) $(+link-before-libc) $(rtld-LDFLAGS) \
 | ||||
| +  $(link-extra-flags) $(link-libc) $(+link-after-libc)
 | ||||
|  $(call after-link,$@) | ||||
|  endef | ||||
|  define +link-tests | ||||
| @@ -552,6 +552,15 @@ ifeq (yes,$(build-shared))
 | ||||
|  link-libc-rpath = -Wl,-rpath=$(rpath-link) | ||||
|  link-libc-rpath-link = -Wl,-rpath-link=$(rpath-link) | ||||
|   | ||||
| +# For programs which are not tests, $(link-libc-rpath-link) is added
 | ||||
| +# directly in $(+link), $(+link-pie) above, so that -Wl,-rpath-link
 | ||||
| +# comes before the expansion of LDLIBS-* and affects libraries added
 | ||||
| +# there.  For shared objects, -Wl,-rpath-link is added via
 | ||||
| +# $(build-shlib-helper) and $(build-module-helper) in Makerules (also
 | ||||
| +# before the expansion of LDLIBS-* variables).
 | ||||
| +
 | ||||
| +# Tests use -Wl,-rpath instead of -Wl,-rpath-link for
 | ||||
| +# build-hardcoded-path-in-tests.
 | ||||
|  ifeq (yes,$(build-hardcoded-path-in-tests)) | ||||
|  link-libc-tests-rpath-link = $(link-libc-rpath) | ||||
|  else | ||||
| @@ -562,7 +571,7 @@ link-libc-before-gnulib = $(common-objpfx)libc.so$(libc.so-version) \
 | ||||
|  			  $(common-objpfx)$(patsubst %,$(libtype.oS),c) \ | ||||
|  			  $(as-needed) $(elf-objpfx)ld.so \ | ||||
|  			  $(no-as-needed) | ||||
| -link-libc = $(link-libc-rpath-link) $(link-libc-before-gnulib) $(gnulib)
 | ||||
| +link-libc = $(link-libc-before-gnulib) $(gnulib)
 | ||||
|   | ||||
|  link-libc-tests-after-rpath-link = $(link-libc-before-gnulib) $(gnulib-tests) | ||||
|  link-libc-tests = $(link-libc-tests-rpath-link) \ | ||||
							
								
								
									
										25
									
								
								SOURCES/glibc-rh1639343-6.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								SOURCES/glibc-rh1639343-6.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,25 @@ | ||||
| commit c57afec0a9b318bb691e0f5fa4e9681cf30df7a4 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Fri Apr 26 07:16:56 2019 +0200 | ||||
| 
 | ||||
|     elf: Link sotruss-lib.so with BIND_NOW for --enable-bind-now | ||||
|      | ||||
|     The audit module itself can be linked with BIND_NOW; it does not | ||||
|     affect its functionality. | ||||
|      | ||||
|     This should complete the leftovers from commit | ||||
|     2d6ab5df3b675e96ee587ae6a8c2ce004c6b1ba9 ("Document and fix | ||||
|     --enable-bind-now [BZ #21015]"). | ||||
| 
 | ||||
| diff --git a/elf/Makefile b/elf/Makefile
 | ||||
| index f5285b99e22fe84d..9194339836900b9d 100644
 | ||||
| --- a/elf/Makefile
 | ||||
| +++ b/elf/Makefile
 | ||||
| @@ -133,6 +133,7 @@ install-others += $(inst_auditdir)/sotruss-lib.so
 | ||||
|  install-bin-script += sotruss | ||||
|  generated += sotruss | ||||
|  libof-sotruss-lib = extramodules | ||||
| +LDFLAGS-sotruss-lib.so += $(z-now-$(bind-now))
 | ||||
|  $(objpfx)sotruss-lib.so: $(objpfx)sotruss-lib.os | ||||
|  	$(build-module-asneeded) | ||||
|  $(objpfx)sotruss-lib.so: $(common-objpfx)libc.so $(objpfx)ld.so \ | ||||
							
								
								
									
										41
									
								
								SOURCES/glibc-rh1641982.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								SOURCES/glibc-rh1641982.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,41 @@ | ||||
| commit c3d8dc45c9df199b8334599a6cbd98c9950dba62 | ||||
| Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> | ||||
| Date:   Thu Oct 11 15:18:40 2018 -0300 | ||||
| 
 | ||||
|     x86: Fix Haswell strong flags (BZ#23709) | ||||
|      | ||||
|     Th commit 'Disable TSX on some Haswell processors.' (2702856bf4) changed the | ||||
|     default flags for Haswell models.  Previously, new models were handled by the | ||||
|     default switch path, which assumed a Core i3/i5/i7 if AVX is available. After | ||||
|     the patch, Haswell models (0x3f, 0x3c, 0x45, 0x46) do not set the flags | ||||
|     Fast_Rep_String, Fast_Unaligned_Load, Fast_Unaligned_Copy, and | ||||
|     Prefer_PMINUB_for_stringop (only the TSX one). | ||||
|      | ||||
|     This patch fixes it by disentangle the TSX flag handling from the memory | ||||
|     optimization ones.  The strstr case cited on patch now selects the | ||||
|     __strstr_sse2_unaligned as expected for the Haswell cpu. | ||||
|      | ||||
|     Checked on x86_64-linux-gnu. | ||||
|      | ||||
|             [BZ #23709] | ||||
|             * sysdeps/x86/cpu-features.c (init_cpu_features): Set TSX bits | ||||
|             independently of other flags. | ||||
| 
 | ||||
| diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
 | ||||
| index ea0b64fdb962a934..4695ac80d4148327 100644
 | ||||
| --- a/sysdeps/x86/cpu-features.c
 | ||||
| +++ b/sysdeps/x86/cpu-features.c
 | ||||
| @@ -316,7 +316,13 @@ init_cpu_features (struct cpu_features *cpu_features)
 | ||||
|  		    | bit_arch_Fast_Unaligned_Copy | ||||
|  		    | bit_arch_Prefer_PMINUB_for_stringop); | ||||
|  	      break; | ||||
| +	    }
 | ||||
|   | ||||
| +	 /* Disable TSX on some Haswell processors to avoid TSX on kernels that
 | ||||
| +	    weren't updated with the latest microcode package (which disables
 | ||||
| +	    broken feature by default).  */
 | ||||
| +	 switch (model)
 | ||||
| +	    {
 | ||||
|  	    case 0x3f: | ||||
|  	      /* Xeon E7 v3 with stepping >= 4 has working TSX.  */ | ||||
|  	      if (stepping >= 4) | ||||
							
								
								
									
										230
									
								
								SOURCES/glibc-rh1642094-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										230
									
								
								SOURCES/glibc-rh1642094-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,230 @@ | ||||
| commit bcdaad21d4635931d1bd3b54a7894276925d081d | ||||
| Author: DJ Delorie <dj@delorie.com> | ||||
| Date:   Tue Nov 20 13:24:09 2018 -0500 | ||||
| 
 | ||||
|     malloc: tcache double free check | ||||
|      | ||||
|     * malloc/malloc.c (tcache_entry): Add key field. | ||||
|     (tcache_put): Set it. | ||||
|     (tcache_get): Likewise. | ||||
|     (_int_free): Check for double free in tcache. | ||||
|     * malloc/tst-tcfree1.c: New. | ||||
|     * malloc/tst-tcfree2.c: New. | ||||
|     * malloc/Makefile: Run the new tests. | ||||
|     * manual/probes.texi: Document memory_tcache_double_free probe. | ||||
|      | ||||
|     * dlfcn/dlerror.c (check_free): Prevent double frees. | ||||
| 
 | ||||
| diff --git a/dlfcn/dlerror.c b/dlfcn/dlerror.c
 | ||||
| index 33574faab65628ff..96bf92533335036b 100644
 | ||||
| --- a/dlfcn/dlerror.c
 | ||||
| +++ b/dlfcn/dlerror.c
 | ||||
| @@ -198,7 +198,10 @@ check_free (struct dl_action_result *rec)
 | ||||
|        Dl_info info; | ||||
|        if (_dl_addr (check_free, &info, &map, NULL) != 0 && map->l_ns == 0) | ||||
|  #endif | ||||
| -	free ((char *) rec->errstring);
 | ||||
| +	{
 | ||||
| +	  free ((char *) rec->errstring);
 | ||||
| +	  rec->errstring = NULL;
 | ||||
| +	}
 | ||||
|      } | ||||
|  } | ||||
|   | ||||
| diff --git a/malloc/Makefile b/malloc/Makefile
 | ||||
| index 7d54bad866f63cb8..e6dfbfc14cb3d140 100644
 | ||||
| --- a/malloc/Makefile
 | ||||
| +++ b/malloc/Makefile
 | ||||
| @@ -38,6 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 | ||||
|  	 tst-malloc_info \ | ||||
|  	 tst-malloc-too-large \ | ||||
|  	 tst-malloc-stats-cancellation \ | ||||
| +	 tst-tcfree1 tst-tcfree2 \
 | ||||
|   | ||||
|  tests-static := \ | ||||
|  	 tst-interpose-static-nothread \ | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index e247c77b7d4de26e..c6b0282e783eaeea 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -2888,6 +2888,8 @@ mremap_chunk (mchunkptr p, size_t new_size)
 | ||||
|  typedef struct tcache_entry | ||||
|  { | ||||
|    struct tcache_entry *next; | ||||
| +  /* This field exists to detect double frees.  */
 | ||||
| +  struct tcache_perthread_struct *key;
 | ||||
|  } tcache_entry; | ||||
|   | ||||
|  /* There is one of these for each thread, which contains the | ||||
| @@ -2911,6 +2913,11 @@ tcache_put (mchunkptr chunk, size_t tc_idx)
 | ||||
|  { | ||||
|    tcache_entry *e = (tcache_entry *) chunk2mem (chunk); | ||||
|    assert (tc_idx < TCACHE_MAX_BINS); | ||||
| +
 | ||||
| +  /* Mark this chunk as "in the tcache" so the test in _int_free will
 | ||||
| +     detect a double free.  */
 | ||||
| +  e->key = tcache;
 | ||||
| +
 | ||||
|    e->next = tcache->entries[tc_idx]; | ||||
|    tcache->entries[tc_idx] = e; | ||||
|    ++(tcache->counts[tc_idx]); | ||||
| @@ -2926,6 +2933,7 @@ tcache_get (size_t tc_idx)
 | ||||
|    assert (tcache->entries[tc_idx] > 0); | ||||
|    tcache->entries[tc_idx] = e->next; | ||||
|    --(tcache->counts[tc_idx]); | ||||
| +  e->key = NULL;
 | ||||
|    return (void *) e; | ||||
|  } | ||||
|   | ||||
| @@ -4152,6 +4160,26 @@ _int_free (mstate av, mchunkptr p, int have_lock)
 | ||||
|    { | ||||
|      size_t tc_idx = csize2tidx (size); | ||||
|   | ||||
| +    /* Check to see if it's already in the tcache.  */
 | ||||
| +    tcache_entry *e = (tcache_entry *) chunk2mem (p);
 | ||||
| +
 | ||||
| +    /* This test succeeds on double free.  However, we don't 100%
 | ||||
| +       trust it (it also matches random payload data at a 1 in
 | ||||
| +       2^<size_t> chance), so verify it's not an unlikely coincidence
 | ||||
| +       before aborting.  */
 | ||||
| +    if (__glibc_unlikely (e->key == tcache && tcache))
 | ||||
| +      {
 | ||||
| +	tcache_entry *tmp;
 | ||||
| +	LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
 | ||||
| +	for (tmp = tcache->entries[tc_idx];
 | ||||
| +	     tmp;
 | ||||
| +	     tmp = tmp->next)
 | ||||
| +	  if (tmp == e)
 | ||||
| +	    malloc_printerr ("free(): double free detected in tcache 2");
 | ||||
| +	/* If we get here, it was a coincidence.  We've wasted a few
 | ||||
| +	   cycles, but don't abort.  */
 | ||||
| +      }
 | ||||
| +
 | ||||
|      if (tcache | ||||
|  	&& tc_idx < mp_.tcache_bins | ||||
|  	&& tcache->counts[tc_idx] < mp_.tcache_count) | ||||
| diff --git a/malloc/tst-tcfree1.c b/malloc/tst-tcfree1.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..bc29375ce77304ac
 | ||||
| --- /dev/null
 | ||||
| +++ b/malloc/tst-tcfree1.c
 | ||||
| @@ -0,0 +1,42 @@
 | ||||
| +/* Test that malloc tcache catches double free.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <errno.h>
 | ||||
| +#include <error.h>
 | ||||
| +#include <limits.h>
 | ||||
| +#include <malloc.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <sys/signal.h>
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  /* Do one allocation of any size that fits in tcache.  */
 | ||||
| +  char * volatile x = malloc (32);
 | ||||
| +
 | ||||
| +  free (x); // puts in tcache
 | ||||
| +  free (x); // should abort
 | ||||
| +
 | ||||
| +  printf("FAIL: tcache double free not detected\n");
 | ||||
| +  return 1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define TEST_FUNCTION do_test
 | ||||
| +#define EXPECTED_SIGNAL SIGABRT
 | ||||
| +#include <support/test-driver.c>
 | ||||
| diff --git a/malloc/tst-tcfree2.c b/malloc/tst-tcfree2.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..17f06bacd411c315
 | ||||
| --- /dev/null
 | ||||
| +++ b/malloc/tst-tcfree2.c
 | ||||
| @@ -0,0 +1,48 @@
 | ||||
| +/* Test that malloc tcache catches double free.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <errno.h>
 | ||||
| +#include <error.h>
 | ||||
| +#include <limits.h>
 | ||||
| +#include <malloc.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <sys/signal.h>
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  char * volatile ptrs[20];
 | ||||
| +  int i;
 | ||||
| +
 | ||||
| +  /* Allocate enough small chunks so that when we free them all, the tcache
 | ||||
| +     is full, and the first one we freed is at the end of its linked list.  */
 | ||||
| +#define COUNT 20
 | ||||
| +  for (i=0; i<COUNT; i++)
 | ||||
| +    ptrs[i] = malloc (20);
 | ||||
| +  for (i=0; i<COUNT; i++)
 | ||||
| +    free (ptrs[i]);
 | ||||
| +  free (ptrs[0]);
 | ||||
| +
 | ||||
| +  printf("FAIL: tcache double free\n");
 | ||||
| +  return 1;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define TEST_FUNCTION do_test
 | ||||
| +#define EXPECTED_SIGNAL SIGABRT
 | ||||
| +#include <support/test-driver.c>
 | ||||
| diff --git a/manual/probes.texi b/manual/probes.texi
 | ||||
| index ab2a3102bb350ef4..0ea560ed78bcfd7e 100644
 | ||||
| --- a/manual/probes.texi
 | ||||
| +++ b/manual/probes.texi
 | ||||
| @@ -243,6 +243,18 @@ This probe is triggered when the
 | ||||
|  value of this tunable. | ||||
|  @end deftp | ||||
|   | ||||
| +@deftp Probe memory_tcache_double_free (void *@var{$arg1}, int @var{$arg2})
 | ||||
| +This probe is triggered when @code{free} determines that the memory
 | ||||
| +being freed has probably already been freed, and resides in the
 | ||||
| +per-thread cache.  Note that there is an extremely unlikely chance
 | ||||
| +that this probe will trigger due to random payload data remaining in
 | ||||
| +the allocated memory matching the key used to detect double frees.
 | ||||
| +This probe actually indicates that an expensive linear search of the
 | ||||
| +tcache, looking for a double free, has happened.  Argument @var{$arg1}
 | ||||
| +is the memory location as passed to @code{free}, Argument @var{$arg2}
 | ||||
| +is the tcache bin it resides in.
 | ||||
| +@end deftp
 | ||||
| +
 | ||||
|  @node Mathematical Function Probes | ||||
|  @section Mathematical Function Probes | ||||
|   | ||||
							
								
								
									
										73
									
								
								SOURCES/glibc-rh1642094-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								SOURCES/glibc-rh1642094-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,73 @@ | ||||
| commit affec03b713c82c43a5b025dddc21bde3334f41e | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Nov 26 20:06:37 2018 +0100 | ||||
| 
 | ||||
|     malloc: tcache: Validate tc_idx before checking for double-frees [BZ #23907] | ||||
|      | ||||
|     The previous check could read beyond the end of the tcache entry | ||||
|     array.  If the e->key == tcache cookie check happened to pass, this | ||||
|     would result in crashes. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index c6b0282e783eaeea..13c52f376859562d 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -4159,33 +4159,33 @@ _int_free (mstate av, mchunkptr p, int have_lock)
 | ||||
|  #if USE_TCACHE | ||||
|    { | ||||
|      size_t tc_idx = csize2tidx (size); | ||||
| -
 | ||||
| -    /* Check to see if it's already in the tcache.  */
 | ||||
| -    tcache_entry *e = (tcache_entry *) chunk2mem (p);
 | ||||
| -
 | ||||
| -    /* This test succeeds on double free.  However, we don't 100%
 | ||||
| -       trust it (it also matches random payload data at a 1 in
 | ||||
| -       2^<size_t> chance), so verify it's not an unlikely coincidence
 | ||||
| -       before aborting.  */
 | ||||
| -    if (__glibc_unlikely (e->key == tcache && tcache))
 | ||||
| +    if (tcache != NULL && tc_idx < mp_.tcache_bins)
 | ||||
|        { | ||||
| -	tcache_entry *tmp;
 | ||||
| -	LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
 | ||||
| -	for (tmp = tcache->entries[tc_idx];
 | ||||
| -	     tmp;
 | ||||
| -	     tmp = tmp->next)
 | ||||
| -	  if (tmp == e)
 | ||||
| -	    malloc_printerr ("free(): double free detected in tcache 2");
 | ||||
| -	/* If we get here, it was a coincidence.  We've wasted a few
 | ||||
| -	   cycles, but don't abort.  */
 | ||||
| -      }
 | ||||
| +	/* Check to see if it's already in the tcache.  */
 | ||||
| +	tcache_entry *e = (tcache_entry *) chunk2mem (p);
 | ||||
| +
 | ||||
| +	/* This test succeeds on double free.  However, we don't 100%
 | ||||
| +	   trust it (it also matches random payload data at a 1 in
 | ||||
| +	   2^<size_t> chance), so verify it's not an unlikely
 | ||||
| +	   coincidence before aborting.  */
 | ||||
| +	if (__glibc_unlikely (e->key == tcache))
 | ||||
| +	  {
 | ||||
| +	    tcache_entry *tmp;
 | ||||
| +	    LIBC_PROBE (memory_tcache_double_free, 2, e, tc_idx);
 | ||||
| +	    for (tmp = tcache->entries[tc_idx];
 | ||||
| +		 tmp;
 | ||||
| +		 tmp = tmp->next)
 | ||||
| +	      if (tmp == e)
 | ||||
| +		malloc_printerr ("free(): double free detected in tcache 2");
 | ||||
| +	    /* If we get here, it was a coincidence.  We've wasted a
 | ||||
| +	       few cycles, but don't abort.  */
 | ||||
| +	  }
 | ||||
|   | ||||
| -    if (tcache
 | ||||
| -	&& tc_idx < mp_.tcache_bins
 | ||||
| -	&& tcache->counts[tc_idx] < mp_.tcache_count)
 | ||||
| -      {
 | ||||
| -	tcache_put (p, tc_idx);
 | ||||
| -	return;
 | ||||
| +	if (tcache->counts[tc_idx] < mp_.tcache_count)
 | ||||
| +	  {
 | ||||
| +	    tcache_put (p, tc_idx);
 | ||||
| +	    return;
 | ||||
| +	  }
 | ||||
|        } | ||||
|    } | ||||
|  #endif | ||||
							
								
								
									
										89
									
								
								SOURCES/glibc-rh1642094-3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								SOURCES/glibc-rh1642094-3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,89 @@ | ||||
| commit 7c9a7c68363051cfc5fa1ebb96b3b2c1f82dcb76 | ||||
| Author: DJ Delorie <dj@redhat.com> | ||||
| Date:   Fri Nov 30 22:13:09 2018 -0500 | ||||
| 
 | ||||
|     malloc: Add another test for tcache double free check. | ||||
|      | ||||
|     This one tests for BZ#23907 where the double free | ||||
|     test didn't check the tcache bin bounds before dereferencing | ||||
|     the bin. | ||||
|      | ||||
|     [BZ #23907] | ||||
|     * malloc/tst-tcfree3.c: New. | ||||
|     * malloc/Makefile: Add it. | ||||
| 
 | ||||
| diff --git a/malloc/Makefile b/malloc/Makefile
 | ||||
| index e6dfbfc14cb3d140..388cf7e9ee3a2569 100644
 | ||||
| --- a/malloc/Makefile
 | ||||
| +++ b/malloc/Makefile
 | ||||
| @@ -38,7 +38,7 @@ tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
 | ||||
|  	 tst-malloc_info \ | ||||
|  	 tst-malloc-too-large \ | ||||
|  	 tst-malloc-stats-cancellation \ | ||||
| -	 tst-tcfree1 tst-tcfree2 \
 | ||||
| +	 tst-tcfree1 tst-tcfree2 tst-tcfree3 \
 | ||||
|   | ||||
|  tests-static := \ | ||||
|  	 tst-interpose-static-nothread \ | ||||
| diff --git a/malloc/tst-tcfree3.c b/malloc/tst-tcfree3.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..016d30ddd8114082
 | ||||
| --- /dev/null
 | ||||
| +++ b/malloc/tst-tcfree3.c
 | ||||
| @@ -0,0 +1,56 @@
 | ||||
| +/* Test that malloc tcache catches double free.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <malloc.h>
 | ||||
| +#include <string.h>
 | ||||
| +
 | ||||
| +/* Prevent GCC from optimizing away any malloc/free pairs.  */
 | ||||
| +#pragma GCC optimize ("O0")
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  /* Do two allocation of any size that fit in tcache, and one that
 | ||||
| +     doesn't.  */
 | ||||
| +  int ** volatile a = malloc (32);
 | ||||
| +  int ** volatile b = malloc (32);
 | ||||
| +  /* This is just under the mmap threshold.  */
 | ||||
| +  int ** volatile c = malloc (127 * 1024);
 | ||||
| +
 | ||||
| +  /* The invalid "tcache bucket" we might dereference will likely end
 | ||||
| +     up somewhere within this memory block, so make all the accidental
 | ||||
| +     "next" pointers cause segfaults.  BZ #23907.  */
 | ||||
| +  memset (c, 0xff, 127 * 1024);
 | ||||
| +
 | ||||
| +  free (a); // puts in tcache
 | ||||
| +
 | ||||
| +  /* A is now free and contains the key we use to detect in-tcache.
 | ||||
| +     Copy the key to the other chunks.  */
 | ||||
| +  memcpy (b, a, 32);
 | ||||
| +  memcpy (c, a, 32);
 | ||||
| +
 | ||||
| +  /* This free tests the "are we in the tcache already" loop with a
 | ||||
| +     VALID bin but "coincidental" matching key.  */
 | ||||
| +  free (b); // should NOT abort
 | ||||
| +  /* This free tests the "is it a valid tcache bin" test.  */
 | ||||
| +  free (c); // should NOT abort
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										34
									
								
								SOURCES/glibc-rh1645593.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								SOURCES/glibc-rh1645593.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,34 @@ | ||||
| commit 28669f86f6780a18daca264f32d66b1428c9c6f1 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Thu Sep 6 14:27:03 2018 +0200 | ||||
| 
 | ||||
|     Fix segfault in maybe_script_execute. | ||||
|      | ||||
|     If glibc is built with gcc 8 and -march=z900, | ||||
|     the testcase posix/tst-spawn4-compat crashes with a segfault. | ||||
|      | ||||
|     In function maybe_script_execute, the new_argv array is dynamically | ||||
|     initialized on stack with (argc + 1) elements. | ||||
|     The function wants to add _PATH_BSHELL as the first argument | ||||
|     and writes out of bounds of new_argv. | ||||
|     There is an off-by-one because maybe_script_execute fails to count | ||||
|     the terminating NULL when sizing new_argv. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/unix/sysv/linux/spawni.c (maybe_script_execute): | ||||
|             Increment size of new_argv by one. | ||||
| 
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/spawni.c b/sysdeps/unix/sysv/linux/spawni.c
 | ||||
| index cf0213ece55c675d..85239cedbf2a5ab5 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/spawni.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/spawni.c
 | ||||
| @@ -101,7 +101,7 @@ maybe_script_execute (struct posix_spawn_args *args)
 | ||||
|        ptrdiff_t argc = args->argc; | ||||
|   | ||||
|        /* Construct an argument list for the shell.  */ | ||||
| -      char *new_argv[argc + 1];
 | ||||
| +      char *new_argv[argc + 2];
 | ||||
|        new_argv[0] = (char *) _PATH_BSHELL; | ||||
|        new_argv[1] = (char *) args->file; | ||||
|        if (argc > 1) | ||||
							
								
								
									
										193
									
								
								SOURCES/glibc-rh1645596.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										193
									
								
								SOURCES/glibc-rh1645596.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,193 @@ | ||||
| commit 7a16bdbb9ff4122af0a28dc20996c95352011fdd | ||||
| Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> | ||||
| Date:   Wed Aug 29 16:36:44 2018 -0300 | ||||
| 
 | ||||
|     Fix misreported errno on preadv2/pwritev2 (BZ#23579) | ||||
|      | ||||
|     The fallback code of Linux wrapper for preadv2/pwritev2 executes | ||||
|     regardless of the errno code for preadv2, instead of the case where | ||||
|     the syscall is not supported. | ||||
|      | ||||
|     This fixes it by calling the fallback code iff errno is ENOSYS. The | ||||
|     patch also adds tests for both invalid file descriptor and invalid | ||||
|     iov_len and vector count. | ||||
|      | ||||
|     The only discrepancy between preadv2 and fallback code regarding | ||||
|     error reporting is when an invalid flags are used.  The fallback code | ||||
|     bails out earlier with ENOTSUP instead of EINVAL/EBADF when the syscall | ||||
|     is used. | ||||
|      | ||||
|     Checked on x86_64-linux-gnu on a 4.4.0 and 4.15.0 kernel. | ||||
|      | ||||
|             [BZ #23579] | ||||
|             * misc/tst-preadvwritev2-common.c (do_test_with_invalid_fd): New | ||||
|             test. | ||||
|             * misc/tst-preadvwritev2.c, misc/tst-preadvwritev64v2.c (do_test): | ||||
|             Call do_test_with_invalid_fd. | ||||
|             * sysdeps/unix/sysv/linux/preadv2.c (preadv2): Use fallback code iff | ||||
|             errno is ENOSYS. | ||||
|             * sysdeps/unix/sysv/linux/preadv64v2.c (preadv64v2): Likewise. | ||||
|             * sysdeps/unix/sysv/linux/pwritev2.c (pwritev2): Likewise. | ||||
|             * sysdeps/unix/sysv/linux/pwritev64v2.c (pwritev64v2): Likewise. | ||||
| 
 | ||||
| diff --git a/misc/tst-preadvwritev2-common.c b/misc/tst-preadvwritev2-common.c
 | ||||
| index f889a21544947042..50b9da3fea56d288 100644
 | ||||
| --- a/misc/tst-preadvwritev2-common.c
 | ||||
| +++ b/misc/tst-preadvwritev2-common.c
 | ||||
| @@ -19,9 +19,6 @@
 | ||||
|  #include <limits.h> | ||||
|  #include <support/check.h> | ||||
|   | ||||
| -static void
 | ||||
| -do_test_with_invalid_flags (void)
 | ||||
| -{
 | ||||
|  #ifndef RWF_HIPRI | ||||
|  # define RWF_HIPRI 0 | ||||
|  #endif | ||||
| @@ -39,6 +36,68 @@ do_test_with_invalid_flags (void)
 | ||||
|  #endif | ||||
|  #define RWF_SUPPORTED	(RWF_HIPRI | RWF_DSYNC | RWF_SYNC | RWF_NOWAIT \ | ||||
|  			 | RWF_APPEND) | ||||
| +
 | ||||
| +static void
 | ||||
| +do_test_with_invalid_fd (void)
 | ||||
| +{
 | ||||
| +  char buf[256];
 | ||||
| +  struct iovec iov = { buf, sizeof buf };
 | ||||
| +
 | ||||
| +  /* Check with flag being 0 to use the fallback code which calls pwritev
 | ||||
| +     or writev.  */
 | ||||
| +  TEST_VERIFY (preadv2 (-1, &iov, 1, -1, 0) == -1);
 | ||||
| +  TEST_COMPARE (errno, EBADF);
 | ||||
| +  TEST_VERIFY (pwritev2 (-1, &iov, 1, -1, 0) == -1);
 | ||||
| +  TEST_COMPARE (errno, EBADF);
 | ||||
| +
 | ||||
| +  /* Same tests as before but with flags being different than 0.  Since
 | ||||
| +     there is no emulation for any flag value, fallback code returns
 | ||||
| +     ENOTSUP.  This is different running on a kernel with preadv2/pwritev2
 | ||||
| +     support, where EBADF is returned).  */
 | ||||
| +  TEST_VERIFY (preadv2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
 | ||||
| +  TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
 | ||||
| +  TEST_VERIFY (pwritev2 (-1, &iov, 1, 0, RWF_HIPRI) == -1);
 | ||||
| +  TEST_VERIFY (errno == EBADF || errno == ENOTSUP);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +do_test_with_invalid_iov (void)
 | ||||
| +{
 | ||||
| +  {
 | ||||
| +    char buf[256];
 | ||||
| +    struct iovec iov;
 | ||||
| +
 | ||||
| +    iov.iov_base = buf;
 | ||||
| +    iov.iov_len = (size_t)SSIZE_MAX + 1;
 | ||||
| +
 | ||||
| +    TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, 0) == -1);
 | ||||
| +    TEST_COMPARE (errno, EINVAL);
 | ||||
| +    TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, 0) == -1);
 | ||||
| +    TEST_COMPARE (errno, EINVAL);
 | ||||
| +
 | ||||
| +    /* Same as for invalid file descriptor tests, emulation fallback
 | ||||
| +       first checks for flag value and return ENOTSUP.  */
 | ||||
| +    TEST_VERIFY (preadv2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
 | ||||
| +    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
 | ||||
| +    TEST_VERIFY (pwritev2 (temp_fd, &iov, 1, 0, RWF_HIPRI) == -1);
 | ||||
| +    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
 | ||||
| +  }
 | ||||
| +
 | ||||
| +  {
 | ||||
| +    /* An invalid iovec buffer should trigger an invalid memory access
 | ||||
| +       or an error (Linux for instance returns EFAULT).  */
 | ||||
| +    struct iovec iov[IOV_MAX+1] = { 0 };
 | ||||
| +
 | ||||
| +    TEST_VERIFY (preadv2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
 | ||||
| +    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
 | ||||
| +    TEST_VERIFY (pwritev2 (temp_fd, iov, IOV_MAX + 1, 0, RWF_HIPRI) == -1);
 | ||||
| +    TEST_VERIFY (errno == EINVAL || errno == ENOTSUP);
 | ||||
| +  }
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +do_test_with_invalid_flags (void)
 | ||||
| +{
 | ||||
|    /* Set the next bit from the mask of all supported flags.  */ | ||||
|    int invalid_flag = RWF_SUPPORTED != 0 ? __builtin_clz (RWF_SUPPORTED) : 2; | ||||
|    invalid_flag = 0x1 << ((sizeof (int) * CHAR_BIT) - invalid_flag); | ||||
| diff --git a/misc/tst-preadvwritev2.c b/misc/tst-preadvwritev2.c
 | ||||
| index be22802dbe00317f..cb58cbe41ecc639d 100644
 | ||||
| --- a/misc/tst-preadvwritev2.c
 | ||||
| +++ b/misc/tst-preadvwritev2.c
 | ||||
| @@ -30,6 +30,8 @@ do_test (void)
 | ||||
|  { | ||||
|    do_test_with_invalid_flags (); | ||||
|    do_test_without_offset (); | ||||
| +  do_test_with_invalid_fd ();
 | ||||
| +  do_test_with_invalid_iov ();
 | ||||
|   | ||||
|    return do_test_with_offset (0); | ||||
|  } | ||||
| diff --git a/misc/tst-preadvwritev64v2.c b/misc/tst-preadvwritev64v2.c
 | ||||
| index 8d3cc32b284dbf4c..6a9de54c786acc53 100644
 | ||||
| --- a/misc/tst-preadvwritev64v2.c
 | ||||
| +++ b/misc/tst-preadvwritev64v2.c
 | ||||
| @@ -32,6 +32,8 @@ do_test (void)
 | ||||
|  { | ||||
|    do_test_with_invalid_flags (); | ||||
|    do_test_without_offset (); | ||||
| +  do_test_with_invalid_fd ();
 | ||||
| +  do_test_with_invalid_iov ();
 | ||||
|   | ||||
|    return do_test_with_offset (0); | ||||
|  } | ||||
| diff --git a/sysdeps/unix/sysv/linux/preadv2.c b/sysdeps/unix/sysv/linux/preadv2.c
 | ||||
| index c8bf0764ef2629fc..bb08cbc5fd96962e 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/preadv2.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/preadv2.c
 | ||||
| @@ -32,7 +32,7 @@ preadv2 (int fd, const struct iovec *vector, int count, off_t offset,
 | ||||
|  # ifdef __NR_preadv2 | ||||
|    ssize_t result = SYSCALL_CANCEL (preadv2, fd, vector, count, | ||||
|  				   LO_HI_LONG (offset), flags); | ||||
| -  if (result >= 0)
 | ||||
| +  if (result >= 0 || errno != ENOSYS)
 | ||||
|      return result; | ||||
|  # endif | ||||
|    /* Trying to emulate the preadv2 syscall flags is troublesome: | ||||
| diff --git a/sysdeps/unix/sysv/linux/preadv64v2.c b/sysdeps/unix/sysv/linux/preadv64v2.c
 | ||||
| index d7400a0252a8c6a1..b72a047347b1db0e 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/preadv64v2.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/preadv64v2.c
 | ||||
| @@ -30,7 +30,7 @@ preadv64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
 | ||||
|  #ifdef __NR_preadv64v2 | ||||
|    ssize_t result = SYSCALL_CANCEL (preadv64v2, fd, vector, count, | ||||
|  				   LO_HI_LONG (offset), flags); | ||||
| -  if (result >= 0)
 | ||||
| +  if (result >= 0 || errno != ENOSYS)
 | ||||
|      return result; | ||||
|  #endif | ||||
|    /* Trying to emulate the preadv2 syscall flags is troublesome: | ||||
| diff --git a/sysdeps/unix/sysv/linux/pwritev2.c b/sysdeps/unix/sysv/linux/pwritev2.c
 | ||||
| index 29c2264c8f3d949a..26333ebd43c5f0af 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/pwritev2.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/pwritev2.c
 | ||||
| @@ -28,7 +28,7 @@ pwritev2 (int fd, const struct iovec *vector, int count, off_t offset,
 | ||||
|  # ifdef __NR_pwritev2 | ||||
|    ssize_t result = SYSCALL_CANCEL (pwritev2, fd, vector, count, | ||||
|  				   LO_HI_LONG (offset), flags); | ||||
| -  if (result >= 0)
 | ||||
| +  if (result >= 0 || errno != ENOSYS)
 | ||||
|      return result; | ||||
|  # endif | ||||
|    /* Trying to emulate the pwritev2 syscall flags is troublesome: | ||||
| diff --git a/sysdeps/unix/sysv/linux/pwritev64v2.c b/sysdeps/unix/sysv/linux/pwritev64v2.c
 | ||||
| index 42da321149bce40d..17ea905aa6a8db94 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/pwritev64v2.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/pwritev64v2.c
 | ||||
| @@ -30,7 +30,7 @@ pwritev64v2 (int fd, const struct iovec *vector, int count, off64_t offset,
 | ||||
|  #ifdef __NR_pwritev64v2 | ||||
|    ssize_t result = SYSCALL_CANCEL (pwritev64v2, fd, vector, count, | ||||
|  				   LO_HI_LONG (offset), flags); | ||||
| -  if (result >= 0)
 | ||||
| +  if (result >= 0 || errno != ENOSYS)
 | ||||
|      return result; | ||||
|  #endif | ||||
|    /* Trying to emulate the pwritev2 syscall flags is troublesome: | ||||
							
								
								
									
										33
									
								
								SOURCES/glibc-rh1645597.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								SOURCES/glibc-rh1645597.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,33 @@ | ||||
| commit dae3ed958c3d0090838e49ff4f78c201262b1cf0 | ||||
| Author: Rafal Luzynski <digitalfreak@lingonborough.com> | ||||
| Date:   Tue Oct 2 23:34:18 2018 +0200 | ||||
| 
 | ||||
|     kl_GL: Fix spelling of Sunday, should be "sapaat" (bug 20209). | ||||
|      | ||||
|     Although CLDR says otherwise, it is confirmed by Oqaasileriffik, the | ||||
|     official Greenlandic language regulator, that this change is correct. | ||||
|      | ||||
|             [BZ #20209] | ||||
|             * localedata/locales/kl_GL: (abday): Fix spelling of Sun (Sunday), | ||||
|             should be "sap" rather than "sab". | ||||
|             (day): Fix spelling of Sunday, should be "sapaat" rather than | ||||
|             "sabaat". | ||||
| 
 | ||||
| diff --git a/localedata/locales/kl_GL b/localedata/locales/kl_GL
 | ||||
| index 5ab14a31aade8644..5723ce7dcf9c5742 100644
 | ||||
| --- a/localedata/locales/kl_GL
 | ||||
| +++ b/localedata/locales/kl_GL
 | ||||
| @@ -70,11 +70,11 @@ copy "da_DK"
 | ||||
|  END LC_NUMERIC | ||||
|   | ||||
|  LC_TIME | ||||
| -abday    "sab";"ata";/
 | ||||
| +abday    "sap";"ata";/
 | ||||
|           "mar";"pin";/ | ||||
|           "sis";"tal";/ | ||||
|           "arf" | ||||
| -day      "sabaat";/
 | ||||
| +day      "sapaat";/
 | ||||
|           "ataasinngorneq";/ | ||||
|           "marlunngorneq";/ | ||||
|           "pingasunngorneq";/ | ||||
							
								
								
									
										134
									
								
								SOURCES/glibc-rh1645601.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								SOURCES/glibc-rh1645601.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | ||||
| commit 7b1f9406761331cf35fe521fbdb592beecf68a2c | ||||
| Author: H.J. Lu <hjl.tools@gmail.com> | ||||
| Date:   Fri Sep 28 13:31:19 2018 -0700 | ||||
| 
 | ||||
|     i386: Use _dl_runtime_[resolve|profile]_shstk for SHSTK [BZ #23716] | ||||
|      | ||||
|     When elf_machine_runtime_setup is called to set up resolver, it should | ||||
|     use _dl_runtime_resolve_shstk or _dl_runtime_profile_shstk if SHSTK is | ||||
|     enabled by kernel. | ||||
|      | ||||
|     Tested on i686 with and without --enable-cet as well as on CET emulator | ||||
|     with --enable-cet. | ||||
|      | ||||
|             [BZ #23716] | ||||
|             * sysdeps/i386/dl-cet.c: Removed. | ||||
|             * sysdeps/i386/dl-machine.h (_dl_runtime_resolve_shstk): New | ||||
|             prototype. | ||||
|             (_dl_runtime_profile_shstk): Likewise. | ||||
|             (elf_machine_runtime_setup): Use _dl_runtime_profile_shstk or | ||||
|             _dl_runtime_resolve_shstk if SHSTK is enabled by kernel. | ||||
|      | ||||
|     Signed-off-by: H.J. Lu <hjl.tools@gmail.com> | ||||
| 
 | ||||
| diff --git a/sysdeps/i386/dl-cet.c b/sysdeps/i386/dl-cet.c
 | ||||
| deleted file mode 100644 | ||||
| index 5d9a4e8d5179b572..0000000000000000
 | ||||
| --- a/sysdeps/i386/dl-cet.c
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,67 +0,0 @@
 | ||||
| -/* Linux/i386 CET initializers function.
 | ||||
| -   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -
 | ||||
| -#define LINKAGE static inline
 | ||||
| -#define _dl_cet_check cet_check
 | ||||
| -#include <sysdeps/x86/dl-cet.c>
 | ||||
| -#undef _dl_cet_check
 | ||||
| -
 | ||||
| -#ifdef SHARED
 | ||||
| -void
 | ||||
| -_dl_cet_check (struct link_map *main_map, const char *program)
 | ||||
| -{
 | ||||
| -  cet_check (main_map, program);
 | ||||
| -
 | ||||
| -  if ((GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK))
 | ||||
| -    {
 | ||||
| -      /* Replace _dl_runtime_resolve and _dl_runtime_profile with
 | ||||
| -         _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk,
 | ||||
| -	 respectively if SHSTK is enabled.  */
 | ||||
| -      extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden;
 | ||||
| -      extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
 | ||||
| -      extern void _dl_runtime_profile (Elf32_Word) attribute_hidden;
 | ||||
| -      extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden;
 | ||||
| -      unsigned int i;
 | ||||
| -      struct link_map *l;
 | ||||
| -      Elf32_Addr *got;
 | ||||
| -
 | ||||
| -      if (main_map->l_info[DT_JMPREL])
 | ||||
| -	{
 | ||||
| -	  got = (Elf32_Addr *) D_PTR (main_map, l_info[DT_PLTGOT]);
 | ||||
| -	  if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
 | ||||
| -	    got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
 | ||||
| -	  else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
 | ||||
| -	    got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;
 | ||||
| -	}
 | ||||
| -
 | ||||
| -      i = main_map->l_searchlist.r_nlist;
 | ||||
| -      while (i-- > 0)
 | ||||
| -	{
 | ||||
| -	  l = main_map->l_initfini[i];
 | ||||
| -	  if (l->l_info[DT_JMPREL])
 | ||||
| -	    {
 | ||||
| -	      got = (Elf32_Addr *) D_PTR (l, l_info[DT_PLTGOT]);
 | ||||
| -	      if (got[2] == (Elf32_Addr) &_dl_runtime_resolve)
 | ||||
| -		got[2] = (Elf32_Addr) &_dl_runtime_resolve_shstk;
 | ||||
| -	      else if (got[2] == (Elf32_Addr) &_dl_runtime_profile)
 | ||||
| -		got[2] = (Elf32_Addr) &_dl_runtime_profile_shstk;
 | ||||
| -	    }
 | ||||
| -	}
 | ||||
| -    }
 | ||||
| -}
 | ||||
| -#endif
 | ||||
| diff --git a/sysdeps/i386/dl-machine.h b/sysdeps/i386/dl-machine.h
 | ||||
| index 1afdcbd9ea2626e4..f6cfb90e21015250 100644
 | ||||
| --- a/sysdeps/i386/dl-machine.h
 | ||||
| +++ b/sysdeps/i386/dl-machine.h
 | ||||
| @@ -67,6 +67,11 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 | ||||
|    Elf32_Addr *got; | ||||
|    extern void _dl_runtime_resolve (Elf32_Word) attribute_hidden; | ||||
|    extern void _dl_runtime_profile (Elf32_Word) attribute_hidden; | ||||
| +  extern void _dl_runtime_resolve_shstk (Elf32_Word) attribute_hidden;
 | ||||
| +  extern void _dl_runtime_profile_shstk (Elf32_Word) attribute_hidden;
 | ||||
| +  /* Check if SHSTK is enabled by kernel.  */
 | ||||
| +  bool shstk_enabled
 | ||||
| +    = (GL(dl_x86_feature_1)[0] & GNU_PROPERTY_X86_FEATURE_1_SHSTK) != 0;
 | ||||
|   | ||||
|    if (l->l_info[DT_JMPREL] && lazy) | ||||
|      { | ||||
| @@ -93,7 +98,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 | ||||
|  	 end in this function.  */ | ||||
|        if (__glibc_unlikely (profile)) | ||||
|  	{ | ||||
| -	  got[2] = (Elf32_Addr) &_dl_runtime_profile;
 | ||||
| +	  got[2] = (shstk_enabled
 | ||||
| +		    ? (Elf32_Addr) &_dl_runtime_profile_shstk
 | ||||
| +		    : (Elf32_Addr) &_dl_runtime_profile);
 | ||||
|   | ||||
|  	  if (GLRO(dl_profile) != NULL | ||||
|  	      && _dl_name_match_p (GLRO(dl_profile), l)) | ||||
| @@ -104,7 +111,9 @@ elf_machine_runtime_setup (struct link_map *l, int lazy, int profile)
 | ||||
|        else | ||||
|  	/* This function will get called to fix up the GOT entry indicated by | ||||
|  	   the offset on the stack, and then jump to the resolved address.  */ | ||||
| -	got[2] = (Elf32_Addr) &_dl_runtime_resolve;
 | ||||
| +	got[2] = (shstk_enabled
 | ||||
| +		  ? (Elf32_Addr) &_dl_runtime_resolve_shstk
 | ||||
| +		  : (Elf32_Addr) &_dl_runtime_resolve);
 | ||||
|      } | ||||
|   | ||||
|    return lazy; | ||||
							
								
								
									
										738
									
								
								SOURCES/glibc-rh1645604.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										738
									
								
								SOURCES/glibc-rh1645604.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,738 @@ | ||||
| commit 403b4feb22dcbc85ace72a361d2a951380372471 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Wed Oct 17 12:23:04 2018 +0200 | ||||
| 
 | ||||
|     Fix race in pthread_mutex_lock while promoting to PTHREAD_MUTEX_ELISION_NP [BZ #23275] | ||||
|      | ||||
|     The race leads either to pthread_mutex_destroy returning EBUSY | ||||
|     or triggering an assertion (See description in bugzilla). | ||||
|      | ||||
|     This patch is fixing the race by ensuring that the elision path is | ||||
|     used in all cases if elision is enabled by the GLIBC_TUNABLES framework. | ||||
|      | ||||
|     The __kind variable in struct __pthread_mutex_s is accessed concurrently. | ||||
|     Therefore we are now using the atomic macros. | ||||
|      | ||||
|     The new testcase tst-mutex10 is triggering the race on s390x and intel. | ||||
|     Presumably also on power, but I don't have access to a power machine | ||||
|     with lock-elision. At least the code for power is the same as on the other | ||||
|     two architectures. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             [BZ #23275] | ||||
|             * nptl/tst-mutex10.c: New File. | ||||
|             * nptl/Makefile (tests): Add tst-mutex10. | ||||
|             (tst-mutex10-ENV): New variable. | ||||
|             * sysdeps/unix/sysv/linux/s390/force-elision.h: (FORCE_ELISION): | ||||
|             Ensure that elision path is used if elision is available. | ||||
|             * sysdeps/unix/sysv/linux/powerpc/force-elision.h (FORCE_ELISION): | ||||
|             Likewise. | ||||
|             * sysdeps/unix/sysv/linux/x86/force-elision.h: (FORCE_ELISION): | ||||
|             Likewise. | ||||
|             * nptl/pthreadP.h (PTHREAD_MUTEX_TYPE, PTHREAD_MUTEX_TYPE_ELISION) | ||||
|             (PTHREAD_MUTEX_PSHARED): Use atomic_load_relaxed. | ||||
|             * nptl/pthread_mutex_consistent.c (pthread_mutex_consistent): Likewise. | ||||
|             * nptl/pthread_mutex_getprioceiling.c (pthread_mutex_getprioceiling): | ||||
|             Likewise. | ||||
|             * nptl/pthread_mutex_lock.c (__pthread_mutex_lock_full) | ||||
|             (__pthread_mutex_cond_lock_adjust): Likewise. | ||||
|             * nptl/pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): | ||||
|             Likewise. | ||||
|             * nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock): Likewise. | ||||
|             * nptl/pthread_mutex_trylock.c (__pthread_mutex_trylock): Likewise. | ||||
|             * nptl/pthread_mutex_unlock.c (__pthread_mutex_unlock_full): Likewise. | ||||
|             * sysdeps/nptl/bits/thread-shared-types.h (struct __pthread_mutex_s): | ||||
|             Add comments. | ||||
|             * nptl/pthread_mutex_destroy.c (__pthread_mutex_destroy): | ||||
|             Use atomic_load_relaxed and atomic_store_relaxed. | ||||
|             * nptl/pthread_mutex_init.c (__pthread_mutex_init): | ||||
|             Use atomic_store_relaxed. | ||||
| 
 | ||||
| diff --git a/nptl/Makefile b/nptl/Makefile
 | ||||
| index be8066524cdc57db..49b6faa330c492e0 100644
 | ||||
| --- a/nptl/Makefile
 | ||||
| +++ b/nptl/Makefile
 | ||||
| @@ -241,9 +241,9 @@ LDLIBS-tst-minstack-throw = -lstdc++
 | ||||
|   | ||||
|  tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \ | ||||
|  	tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \ | ||||
| -	tst-mutex7 tst-mutex9 tst-mutex5a tst-mutex7a tst-mutex7robust \
 | ||||
| -	tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
 | ||||
| -	tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
 | ||||
| +	tst-mutex7 tst-mutex9 tst-mutex10 tst-mutex5a tst-mutex7a \
 | ||||
| +	tst-mutex7robust tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 \
 | ||||
| +	tst-mutexpi5 tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a \
 | ||||
|  	tst-mutexpi9 \ | ||||
|  	tst-spin1 tst-spin2 tst-spin3 tst-spin4 \ | ||||
|  	tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \ | ||||
| @@ -709,6 +709,8 @@ endif
 | ||||
|   | ||||
|  $(objpfx)tst-compat-forwarder: $(objpfx)tst-compat-forwarder-mod.so | ||||
|   | ||||
| +tst-mutex10-ENV = GLIBC_TUNABLES=glibc.elision.enable=1
 | ||||
| +
 | ||||
|  # The tests here better do not run in parallel | ||||
|  ifneq ($(filter %tests,$(MAKECMDGOALS)),) | ||||
|  .NOTPARALLEL: | ||||
| diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
 | ||||
| index 13bdb11133536195..19efe1e35feed5be 100644
 | ||||
| --- a/nptl/pthreadP.h
 | ||||
| +++ b/nptl/pthreadP.h
 | ||||
| @@ -110,19 +110,23 @@ enum
 | ||||
|  }; | ||||
|  #define PTHREAD_MUTEX_PSHARED_BIT 128 | ||||
|   | ||||
| +/* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +   in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
|  #define PTHREAD_MUTEX_TYPE(m) \ | ||||
| -  ((m)->__data.__kind & 127)
 | ||||
| +  (atomic_load_relaxed (&((m)->__data.__kind)) & 127)
 | ||||
|  /* Don't include NO_ELISION, as that type is always the same | ||||
|     as the underlying lock type.  */ | ||||
|  #define PTHREAD_MUTEX_TYPE_ELISION(m) \ | ||||
| -  ((m)->__data.__kind & (127|PTHREAD_MUTEX_ELISION_NP))
 | ||||
| +  (atomic_load_relaxed (&((m)->__data.__kind))	\
 | ||||
| +   & (127 | PTHREAD_MUTEX_ELISION_NP))
 | ||||
|   | ||||
|  #if LLL_PRIVATE == 0 && LLL_SHARED == 128 | ||||
|  # define PTHREAD_MUTEX_PSHARED(m) \ | ||||
| -  ((m)->__data.__kind & 128)
 | ||||
| +  (atomic_load_relaxed (&((m)->__data.__kind)) & 128)
 | ||||
|  #else | ||||
|  # define PTHREAD_MUTEX_PSHARED(m) \ | ||||
| -  (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
 | ||||
| +  ((atomic_load_relaxed (&((m)->__data.__kind)) & 128)	\
 | ||||
| +   ? LLL_SHARED : LLL_PRIVATE)
 | ||||
|  #endif | ||||
|   | ||||
|  /* The kernel when waking robust mutexes on exit never uses | ||||
| diff --git a/nptl/pthread_mutex_consistent.c b/nptl/pthread_mutex_consistent.c
 | ||||
| index 85b8e1a6cb027e9b..4fbd875430439e4d 100644
 | ||||
| --- a/nptl/pthread_mutex_consistent.c
 | ||||
| +++ b/nptl/pthread_mutex_consistent.c
 | ||||
| @@ -23,8 +23,11 @@
 | ||||
|  int | ||||
|  pthread_mutex_consistent (pthread_mutex_t *mutex) | ||||
|  { | ||||
| -  /* Test whether this is a robust mutex with a dead owner.  */
 | ||||
| -  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
 | ||||
| +  /* Test whether this is a robust mutex with a dead owner.
 | ||||
| +     See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +  if ((atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +       & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
 | ||||
|        || mutex->__data.__owner != PTHREAD_MUTEX_INCONSISTENT) | ||||
|      return EINVAL; | ||||
|   | ||||
| diff --git a/nptl/pthread_mutex_destroy.c b/nptl/pthread_mutex_destroy.c
 | ||||
| index 5a22611541995778..713ea684962fefc1 100644
 | ||||
| --- a/nptl/pthread_mutex_destroy.c
 | ||||
| +++ b/nptl/pthread_mutex_destroy.c
 | ||||
| @@ -27,12 +27,17 @@ __pthread_mutex_destroy (pthread_mutex_t *mutex)
 | ||||
|  { | ||||
|    LIBC_PROBE (mutex_destroy, 1, mutex); | ||||
|   | ||||
| -  if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
 | ||||
| +  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +  if ((atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +       & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0
 | ||||
|        && mutex->__data.__nusers != 0) | ||||
|      return EBUSY; | ||||
|   | ||||
| -  /* Set to an invalid value.  */
 | ||||
| -  mutex->__data.__kind = -1;
 | ||||
| +  /* Set to an invalid value.  Relaxed MO is enough as it is undefined behavior
 | ||||
| +     if the mutex is used after it has been destroyed.  But you can reinitialize
 | ||||
| +     it with pthread_mutex_init.  */
 | ||||
| +  atomic_store_relaxed (&(mutex->__data.__kind), -1);
 | ||||
|   | ||||
|    return 0; | ||||
|  } | ||||
| diff --git a/nptl/pthread_mutex_getprioceiling.c b/nptl/pthread_mutex_getprioceiling.c
 | ||||
| index efa37b0d99201f57..ee85949578475f3a 100644
 | ||||
| --- a/nptl/pthread_mutex_getprioceiling.c
 | ||||
| +++ b/nptl/pthread_mutex_getprioceiling.c
 | ||||
| @@ -24,7 +24,9 @@
 | ||||
|  int | ||||
|  pthread_mutex_getprioceiling (const pthread_mutex_t *mutex, int *prioceiling) | ||||
|  { | ||||
| -  if (__builtin_expect ((mutex->__data.__kind
 | ||||
| +  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +  if (__builtin_expect ((atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
|  			 & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0, 0)) | ||||
|      return EINVAL; | ||||
|   | ||||
| diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c
 | ||||
| index d8fe4737289c0bd7..5cf290c272e27915 100644
 | ||||
| --- a/nptl/pthread_mutex_init.c
 | ||||
| +++ b/nptl/pthread_mutex_init.c
 | ||||
| @@ -101,7 +101,7 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
 | ||||
|    memset (mutex, '\0', __SIZEOF_PTHREAD_MUTEX_T); | ||||
|   | ||||
|    /* Copy the values from the attribute.  */ | ||||
| -  mutex->__data.__kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
 | ||||
| +  int mutex_kind = imutexattr->mutexkind & ~PTHREAD_MUTEXATTR_FLAG_BITS;
 | ||||
|   | ||||
|    if ((imutexattr->mutexkind & PTHREAD_MUTEXATTR_FLAG_ROBUST) != 0) | ||||
|      { | ||||
| @@ -111,17 +111,17 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
 | ||||
|  	return ENOTSUP; | ||||
|  #endif | ||||
|   | ||||
| -      mutex->__data.__kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +      mutex_kind |= PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
|      } | ||||
|   | ||||
|    switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK) | ||||
|      { | ||||
|      case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: | ||||
| -      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
 | ||||
| +      mutex_kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
 | ||||
|        break; | ||||
|   | ||||
|      case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT: | ||||
| -      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
 | ||||
| +      mutex_kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
 | ||||
|   | ||||
|        int ceiling = (imutexattr->mutexkind | ||||
|  		     & PTHREAD_MUTEXATTR_PRIO_CEILING_MASK) | ||||
| @@ -145,7 +145,11 @@ __pthread_mutex_init (pthread_mutex_t *mutex,
 | ||||
|       FUTEX_PRIVATE_FLAG FUTEX_WAKE.  */ | ||||
|    if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED | ||||
|  				| PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0) | ||||
| -    mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT;
 | ||||
| +    mutex_kind |= PTHREAD_MUTEX_PSHARED_BIT;
 | ||||
| +
 | ||||
| +  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +  atomic_store_relaxed (&(mutex->__data.__kind), mutex_kind);
 | ||||
|   | ||||
|    /* Default values: mutex not used yet.  */ | ||||
|    // mutex->__count = 0;	already done by memset | ||||
| diff --git a/nptl/pthread_mutex_lock.c b/nptl/pthread_mutex_lock.c
 | ||||
| index 1519c142bd6ec5cc..29cc143e6cbf2421 100644
 | ||||
| --- a/nptl/pthread_mutex_lock.c
 | ||||
| +++ b/nptl/pthread_mutex_lock.c
 | ||||
| @@ -62,6 +62,8 @@ static int __pthread_mutex_lock_full (pthread_mutex_t *mutex)
 | ||||
|  int | ||||
|  __pthread_mutex_lock (pthread_mutex_t *mutex) | ||||
|  { | ||||
| +  /* See concurrency notes regarding mutex type which is loaded from __kind
 | ||||
| +     in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
|    unsigned int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); | ||||
|   | ||||
|    LIBC_PROBE (mutex_entry, 1, mutex); | ||||
| @@ -350,8 +352,14 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
 | ||||
|      case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: | ||||
|      case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: | ||||
|        { | ||||
| -	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| -	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +	int kind, robust;
 | ||||
| +	{
 | ||||
| +	  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +	  int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
 | ||||
| +	  kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| +	  robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +	}
 | ||||
|   | ||||
|  	if (robust) | ||||
|  	  { | ||||
| @@ -502,7 +510,10 @@ __pthread_mutex_lock_full (pthread_mutex_t *mutex)
 | ||||
|      case PTHREAD_MUTEX_PP_NORMAL_NP: | ||||
|      case PTHREAD_MUTEX_PP_ADAPTIVE_NP: | ||||
|        { | ||||
| -	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| +	/* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	   in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +	int kind = atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +	  & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
|   | ||||
|  	oldval = mutex->__data.__lock; | ||||
|   | ||||
| @@ -607,15 +618,18 @@ hidden_def (__pthread_mutex_lock)
 | ||||
|  void | ||||
|  __pthread_mutex_cond_lock_adjust (pthread_mutex_t *mutex) | ||||
|  { | ||||
| -  assert ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
 | ||||
| -  assert ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
 | ||||
| -  assert ((mutex->__data.__kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
 | ||||
| +  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +  int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
 | ||||
| +  assert ((mutex_kind & PTHREAD_MUTEX_PRIO_INHERIT_NP) != 0);
 | ||||
| +  assert ((mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) == 0);
 | ||||
| +  assert ((mutex_kind & PTHREAD_MUTEX_PSHARED_BIT) == 0);
 | ||||
|   | ||||
|    /* Record the ownership.  */ | ||||
|    pid_t id = THREAD_GETMEM (THREAD_SELF, tid); | ||||
|    mutex->__data.__owner = id; | ||||
|   | ||||
| -  if (mutex->__data.__kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
 | ||||
| +  if (mutex_kind == PTHREAD_MUTEX_PI_RECURSIVE_NP)
 | ||||
|      ++mutex->__data.__count; | ||||
|  } | ||||
|  #endif | ||||
| diff --git a/nptl/pthread_mutex_setprioceiling.c b/nptl/pthread_mutex_setprioceiling.c
 | ||||
| index 8594874f8588b7a8..8306cabcf4e56174 100644
 | ||||
| --- a/nptl/pthread_mutex_setprioceiling.c
 | ||||
| +++ b/nptl/pthread_mutex_setprioceiling.c
 | ||||
| @@ -27,9 +27,10 @@ int
 | ||||
|  pthread_mutex_setprioceiling (pthread_mutex_t *mutex, int prioceiling, | ||||
|  			      int *old_ceiling) | ||||
|  { | ||||
| -  /* The low bits of __kind aren't ever changed after pthread_mutex_init,
 | ||||
| -     so we don't need a lock yet.  */
 | ||||
| -  if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
 | ||||
| +  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +  if ((atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +       & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
 | ||||
|      return EINVAL; | ||||
|   | ||||
|    /* See __init_sched_fifo_prio.  */ | ||||
| diff --git a/nptl/pthread_mutex_timedlock.c b/nptl/pthread_mutex_timedlock.c
 | ||||
| index 28237b0e58cfcaf5..888c12fe28b2ebfd 100644
 | ||||
| --- a/nptl/pthread_mutex_timedlock.c
 | ||||
| +++ b/nptl/pthread_mutex_timedlock.c
 | ||||
| @@ -53,6 +53,8 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 | ||||
|    /* We must not check ABSTIME here.  If the thread does not block | ||||
|       abstime must not be checked for a valid value.  */ | ||||
|   | ||||
| +  /* See concurrency notes regarding mutex type which is loaded from __kind
 | ||||
| +     in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
|    switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), | ||||
|  			    PTHREAD_MUTEX_TIMED_NP)) | ||||
|      { | ||||
| @@ -338,8 +340,14 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 | ||||
|      case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: | ||||
|      case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: | ||||
|        { | ||||
| -	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| -	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +	int kind, robust;
 | ||||
| +	{
 | ||||
| +	  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +	  int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
 | ||||
| +	  kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| +	  robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +	}
 | ||||
|   | ||||
|  	if (robust) | ||||
|  	  { | ||||
| @@ -509,7 +517,10 @@ __pthread_mutex_timedlock (pthread_mutex_t *mutex,
 | ||||
|      case PTHREAD_MUTEX_PP_NORMAL_NP: | ||||
|      case PTHREAD_MUTEX_PP_ADAPTIVE_NP: | ||||
|        { | ||||
| -	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| +	/* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	   in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +	int kind = atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +	  & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
|   | ||||
|  	oldval = mutex->__data.__lock; | ||||
|   | ||||
| diff --git a/nptl/pthread_mutex_trylock.c b/nptl/pthread_mutex_trylock.c
 | ||||
| index 7de61f4f688c1537..fa90c1d1e6f5afc2 100644
 | ||||
| --- a/nptl/pthread_mutex_trylock.c
 | ||||
| +++ b/nptl/pthread_mutex_trylock.c
 | ||||
| @@ -36,6 +36,8 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
 | ||||
|    int oldval; | ||||
|    pid_t id = THREAD_GETMEM (THREAD_SELF, tid); | ||||
|   | ||||
| +  /* See concurrency notes regarding mutex type which is loaded from __kind
 | ||||
| +     in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
|    switch (__builtin_expect (PTHREAD_MUTEX_TYPE_ELISION (mutex), | ||||
|  			    PTHREAD_MUTEX_TIMED_NP)) | ||||
|      { | ||||
| @@ -199,8 +201,14 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
 | ||||
|      case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP: | ||||
|      case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP: | ||||
|        { | ||||
| -	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| -	int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +	int kind, robust;
 | ||||
| +	{
 | ||||
| +	  /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	     in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +	  int mutex_kind = atomic_load_relaxed (&(mutex->__data.__kind));
 | ||||
| +	  kind = mutex_kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| +	  robust = mutex_kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +	}
 | ||||
|   | ||||
|  	if (robust) | ||||
|  	  /* Note: robust PI futexes are signaled by setting bit 0.  */ | ||||
| @@ -325,7 +333,10 @@ __pthread_mutex_trylock (pthread_mutex_t *mutex)
 | ||||
|      case PTHREAD_MUTEX_PP_NORMAL_NP: | ||||
|      case PTHREAD_MUTEX_PP_ADAPTIVE_NP: | ||||
|        { | ||||
| -	int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
| +	/* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	   in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +	int kind = atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +	  & PTHREAD_MUTEX_KIND_MASK_NP;
 | ||||
|   | ||||
|  	oldval = mutex->__data.__lock; | ||||
|   | ||||
| diff --git a/nptl/pthread_mutex_unlock.c b/nptl/pthread_mutex_unlock.c
 | ||||
| index 9ea62943b7c6b159..68d04d53955584e5 100644
 | ||||
| --- a/nptl/pthread_mutex_unlock.c
 | ||||
| +++ b/nptl/pthread_mutex_unlock.c
 | ||||
| @@ -35,6 +35,8 @@ int
 | ||||
|  attribute_hidden | ||||
|  __pthread_mutex_unlock_usercnt (pthread_mutex_t *mutex, int decr) | ||||
|  { | ||||
| +  /* See concurrency notes regarding mutex type which is loaded from __kind
 | ||||
| +     in struct __pthread_mutex_s in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
|    int type = PTHREAD_MUTEX_TYPE_ELISION (mutex); | ||||
|    if (__builtin_expect (type & | ||||
|  		~(PTHREAD_MUTEX_KIND_MASK_NP|PTHREAD_MUTEX_ELISION_FLAGS_NP), 0)) | ||||
| @@ -222,13 +224,19 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
 | ||||
|        /* If the previous owner died and the caller did not succeed in | ||||
|  	 making the state consistent, mark the mutex as unrecoverable | ||||
|  	 and make all waiters.  */ | ||||
| -      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
 | ||||
| +      /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	 in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +      if ((atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +	   & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
 | ||||
|  	  && __builtin_expect (mutex->__data.__owner | ||||
|  			       == PTHREAD_MUTEX_INCONSISTENT, 0)) | ||||
|        pi_notrecoverable: | ||||
|         newowner = PTHREAD_MUTEX_NOTRECOVERABLE; | ||||
|   | ||||
| -      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
 | ||||
| +      /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	 in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +      if ((atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +	   & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
 | ||||
|  	{ | ||||
|  	continue_pi_robust: | ||||
|  	  /* Remove mutex from the list. | ||||
| @@ -251,7 +259,10 @@ __pthread_mutex_unlock_full (pthread_mutex_t *mutex, int decr)
 | ||||
|        /* Unlock.  Load all necessary mutex data before releasing the mutex | ||||
|  	 to not violate the mutex destruction requirements (see | ||||
|  	 lll_unlock).  */ | ||||
| -      int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
| +      /* See concurrency notes regarding __kind in struct __pthread_mutex_s
 | ||||
| +	 in sysdeps/nptl/bits/thread-shared-types.h.  */
 | ||||
| +      int robust = atomic_load_relaxed (&(mutex->__data.__kind))
 | ||||
| +	& PTHREAD_MUTEX_ROBUST_NORMAL_NP;
 | ||||
|        private = (robust | ||||
|  		 ? PTHREAD_ROBUST_MUTEX_PSHARED (mutex) | ||||
|  		 : PTHREAD_MUTEX_PSHARED (mutex)); | ||||
| diff --git a/nptl/tst-mutex10.c b/nptl/tst-mutex10.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..e1113ca60a7c8db5
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-mutex10.c
 | ||||
| @@ -0,0 +1,109 @@
 | ||||
| +/* Testing race while enabling lock elision.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <stdint.h>
 | ||||
| +#include <pthread.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#include <getopt.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/xthread.h>
 | ||||
| +
 | ||||
| +static pthread_barrier_t barrier;
 | ||||
| +static pthread_mutex_t mutex;
 | ||||
| +static long long int iteration_count = 1000000;
 | ||||
| +static unsigned int thread_count = 3;
 | ||||
| +
 | ||||
| +static void *
 | ||||
| +thr_func (void *arg)
 | ||||
| +{
 | ||||
| +  long long int i;
 | ||||
| +  for (i = 0; i < iteration_count; i++)
 | ||||
| +    {
 | ||||
| +      if ((uintptr_t) arg == 0)
 | ||||
| +	{
 | ||||
| +	  xpthread_mutex_destroy (&mutex);
 | ||||
| +	  xpthread_mutex_init (&mutex, NULL);
 | ||||
| +	}
 | ||||
| +
 | ||||
| +      xpthread_barrier_wait (&barrier);
 | ||||
| +
 | ||||
| +      /* Test if enabling lock elision works if it is enabled concurrently.
 | ||||
| +	 There was a race in FORCE_ELISION macro which leads to either
 | ||||
| +	 pthread_mutex_destroy returning EBUSY as the owner was recorded
 | ||||
| +	 by pthread_mutex_lock - in "normal mutex" code path - but was not
 | ||||
| +	 resetted in pthread_mutex_unlock - in "elision" code path.
 | ||||
| +	 Or it leads to the assertion in nptl/pthread_mutex_lock.c:
 | ||||
| +	 assert (mutex->__data.__owner == 0);
 | ||||
| +	 Please ensure that the test is run with lock elision:
 | ||||
| +	 export GLIBC_TUNABLES=glibc.elision.enable=1  */
 | ||||
| +      xpthread_mutex_lock (&mutex);
 | ||||
| +      xpthread_mutex_unlock (&mutex);
 | ||||
| +
 | ||||
| +      xpthread_barrier_wait (&barrier);
 | ||||
| +    }
 | ||||
| +  return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  unsigned int i;
 | ||||
| +  printf ("Starting %d threads to run %lld iterations.\n",
 | ||||
| +	  thread_count, iteration_count);
 | ||||
| +
 | ||||
| +  pthread_t *threads = xmalloc (thread_count * sizeof (pthread_t));
 | ||||
| +  xpthread_barrier_init (&barrier, NULL, thread_count);
 | ||||
| +  xpthread_mutex_init (&mutex, NULL);
 | ||||
| +
 | ||||
| +  for (i = 0; i < thread_count; i++)
 | ||||
| +    threads[i] = xpthread_create (NULL, thr_func, (void *) (uintptr_t) i);
 | ||||
| +
 | ||||
| +  for (i = 0; i < thread_count; i++)
 | ||||
| +    xpthread_join (threads[i]);
 | ||||
| +
 | ||||
| +  xpthread_barrier_destroy (&barrier);
 | ||||
| +  free (threads);
 | ||||
| +
 | ||||
| +  return EXIT_SUCCESS;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define OPT_ITERATIONS	10000
 | ||||
| +#define OPT_THREADS	10001
 | ||||
| +#define CMDLINE_OPTIONS						\
 | ||||
| +  { "iterations", required_argument, NULL, OPT_ITERATIONS },	\
 | ||||
| +  { "threads", required_argument, NULL, OPT_THREADS },
 | ||||
| +static void
 | ||||
| +cmdline_process (int c)
 | ||||
| +{
 | ||||
| +  long long int arg = strtoll (optarg, NULL, 0);
 | ||||
| +  switch (c)
 | ||||
| +    {
 | ||||
| +    case OPT_ITERATIONS:
 | ||||
| +      if (arg > 0)
 | ||||
| +	iteration_count = arg;
 | ||||
| +      break;
 | ||||
| +    case OPT_THREADS:
 | ||||
| +      if (arg > 0 && arg < 100)
 | ||||
| +	thread_count = arg;
 | ||||
| +      break;
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +#define CMDLINE_PROCESS cmdline_process
 | ||||
| +#define TIMEOUT 50
 | ||||
| +#include <support/test-driver.c>
 | ||||
| diff --git a/sysdeps/nptl/bits/thread-shared-types.h b/sysdeps/nptl/bits/thread-shared-types.h
 | ||||
| index 1e2092a05d5610f7..05c94e7a710c0eb9 100644
 | ||||
| --- a/sysdeps/nptl/bits/thread-shared-types.h
 | ||||
| +++ b/sysdeps/nptl/bits/thread-shared-types.h
 | ||||
| @@ -124,7 +124,27 @@ struct __pthread_mutex_s
 | ||||
|    unsigned int __nusers; | ||||
|  #endif | ||||
|    /* KIND must stay at this position in the structure to maintain | ||||
| -     binary compatibility with static initializers.  */
 | ||||
| +     binary compatibility with static initializers.
 | ||||
| +
 | ||||
| +     Concurrency notes:
 | ||||
| +     The __kind of a mutex is initialized either by the static
 | ||||
| +     PTHREAD_MUTEX_INITIALIZER or by a call to pthread_mutex_init.
 | ||||
| +
 | ||||
| +     After a mutex has been initialized, the __kind of a mutex is usually not
 | ||||
| +     changed.  BUT it can be set to -1 in pthread_mutex_destroy or elision can
 | ||||
| +     be enabled.  This is done concurrently in the pthread_mutex_*lock functions
 | ||||
| +     by using the macro FORCE_ELISION. This macro is only defined for
 | ||||
| +     architectures which supports lock elision.
 | ||||
| +
 | ||||
| +     For elision, there are the flags PTHREAD_MUTEX_ELISION_NP and
 | ||||
| +     PTHREAD_MUTEX_NO_ELISION_NP which can be set in addition to the already set
 | ||||
| +     type of a mutex.
 | ||||
| +     Before a mutex is initialized, only PTHREAD_MUTEX_NO_ELISION_NP can be set
 | ||||
| +     with pthread_mutexattr_settype.
 | ||||
| +     After a mutex has been initialized, the functions pthread_mutex_*lock can
 | ||||
| +     enable elision - if the mutex-type and the machine supports it - by setting
 | ||||
| +     the flag PTHREAD_MUTEX_ELISION_NP. This is done concurrently. Afterwards
 | ||||
| +     the lock / unlock functions are using specific elision code-paths.  */
 | ||||
|    int __kind; | ||||
|    __PTHREAD_COMPAT_PADDING_MID | ||||
|  #if __PTHREAD_MUTEX_NUSERS_AFTER_KIND | ||||
| diff --git a/sysdeps/unix/sysv/linux/powerpc/force-elision.h b/sysdeps/unix/sysv/linux/powerpc/force-elision.h
 | ||||
| index fe5d6ceade2bad36..d8f5a4b1c7713bd4 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/powerpc/force-elision.h
 | ||||
| +++ b/sysdeps/unix/sysv/linux/powerpc/force-elision.h
 | ||||
| @@ -18,9 +18,45 @@
 | ||||
|   | ||||
|  /* Automatically enable elision for existing user lock kinds.  */ | ||||
|  #define FORCE_ELISION(m, s)						\ | ||||
| -  if (__pthread_force_elision						\
 | ||||
| -      && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)	\
 | ||||
| +  if (__pthread_force_elision)						\
 | ||||
|      {									\ | ||||
| -      mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP;			\
 | ||||
| -      s;								\
 | ||||
| +      /* See concurrency notes regarding __kind in			\
 | ||||
| +	 struct __pthread_mutex_s in					\
 | ||||
| +	 sysdeps/nptl/bits/thread-shared-types.h.			\
 | ||||
| +									\
 | ||||
| +	 There are the following cases for the kind of a mutex		\
 | ||||
| +	 (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags	\
 | ||||
| +	 PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where	\
 | ||||
| +	 only one of both flags can be set):				\
 | ||||
| +	 - both flags are not set:					\
 | ||||
| +	 This is the first lock operation for this mutex.  Enable	\
 | ||||
| +	 elision as it is not enabled so far.				\
 | ||||
| +	 Note: It can happen that multiple threads are calling e.g.	\
 | ||||
| +	 pthread_mutex_lock at the same time as the first lock		\
 | ||||
| +	 operation for this mutex.  Then elision is enabled for this	\
 | ||||
| +	 mutex by multiple threads.  Storing with relaxed MO is enough	\
 | ||||
| +	 as all threads will store the same new value for the kind of	\
 | ||||
| +	 the mutex.  But we have to ensure that we always use the	\
 | ||||
| +	 elision path regardless if this thread has enabled elision or	\
 | ||||
| +	 another one.							\
 | ||||
| +									\
 | ||||
| +	 - PTHREAD_MUTEX_ELISION_NP flag is set:			\
 | ||||
| +	 Elision was already enabled for this mutex by a previous lock	\
 | ||||
| +	 operation.  See case above.  Just use the elision path.	\
 | ||||
| +									\
 | ||||
| +	 - PTHREAD_MUTEX_NO_ELISION_NP flag is set:			\
 | ||||
| +	 Elision was explicitly disabled by pthread_mutexattr_settype.	\
 | ||||
| +	 Do not use the elision path.					\
 | ||||
| +	 Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be	\
 | ||||
| +	 changed after mutex initialization.  */			\
 | ||||
| +      int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind));	\
 | ||||
| +      if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)		\
 | ||||
| +	{								\
 | ||||
| +	  mutex_kind |= PTHREAD_MUTEX_ELISION_NP;			\
 | ||||
| +	  atomic_store_relaxed (&((m)->__data.__kind), mutex_kind);	\
 | ||||
| +	}								\
 | ||||
| +      if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0)			\
 | ||||
| +	{								\
 | ||||
| +	  s;								\
 | ||||
| +	}								\
 | ||||
|      } | ||||
| diff --git a/sysdeps/unix/sysv/linux/s390/force-elision.h b/sysdeps/unix/sysv/linux/s390/force-elision.h
 | ||||
| index d8a1b9972f739cfe..71f32367dd6b6489 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/s390/force-elision.h
 | ||||
| +++ b/sysdeps/unix/sysv/linux/s390/force-elision.h
 | ||||
| @@ -18,9 +18,45 @@
 | ||||
|   | ||||
|  /* Automatically enable elision for existing user lock kinds.  */ | ||||
|  #define FORCE_ELISION(m, s)						\ | ||||
| -  if (__pthread_force_elision						\
 | ||||
| -      && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)	\
 | ||||
| +  if (__pthread_force_elision)						\
 | ||||
|      {									\ | ||||
| -      mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP;			\
 | ||||
| -      s;								\
 | ||||
| +      /* See concurrency notes regarding __kind in			\
 | ||||
| +	 struct __pthread_mutex_s in					\
 | ||||
| +	 sysdeps/nptl/bits/thread-shared-types.h.			\
 | ||||
| +									\
 | ||||
| +	 There are the following cases for the kind of a mutex		\
 | ||||
| +	 (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags	\
 | ||||
| +	 PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where	\
 | ||||
| +	 only one of both flags can be set):				\
 | ||||
| +	 - both flags are not set:					\
 | ||||
| +	 This is the first lock operation for this mutex.  Enable	\
 | ||||
| +	 elision as it is not enabled so far.				\
 | ||||
| +	 Note: It can happen that multiple threads are calling e.g.	\
 | ||||
| +	 pthread_mutex_lock at the same time as the first lock		\
 | ||||
| +	 operation for this mutex.  Then elision is enabled for this	\
 | ||||
| +	 mutex by multiple threads.  Storing with relaxed MO is enough	\
 | ||||
| +	 as all threads will store the same new value for the kind of	\
 | ||||
| +	 the mutex.  But we have to ensure that we always use the	\
 | ||||
| +	 elision path regardless if this thread has enabled elision or	\
 | ||||
| +	 another one.							\
 | ||||
| +									\
 | ||||
| +	 - PTHREAD_MUTEX_ELISION_NP flag is set:			\
 | ||||
| +	 Elision was already enabled for this mutex by a previous lock	\
 | ||||
| +	 operation.  See case above.  Just use the elision path.	\
 | ||||
| +									\
 | ||||
| +	 - PTHREAD_MUTEX_NO_ELISION_NP flag is set:			\
 | ||||
| +	 Elision was explicitly disabled by pthread_mutexattr_settype.	\
 | ||||
| +	 Do not use the elision path.					\
 | ||||
| +	 Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be	\
 | ||||
| +	 changed after mutex initialization.  */			\
 | ||||
| +      int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind));	\
 | ||||
| +      if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)		\
 | ||||
| +	{								\
 | ||||
| +	  mutex_kind |= PTHREAD_MUTEX_ELISION_NP;			\
 | ||||
| +	  atomic_store_relaxed (&((m)->__data.__kind), mutex_kind);	\
 | ||||
| +	}								\
 | ||||
| +      if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0)			\
 | ||||
| +	{								\
 | ||||
| +	  s;								\
 | ||||
| +	}								\
 | ||||
|      } | ||||
| diff --git a/sysdeps/unix/sysv/linux/x86/force-elision.h b/sysdeps/unix/sysv/linux/x86/force-elision.h
 | ||||
| index dd659c908f3046c1..61282d6678d89787 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/x86/force-elision.h
 | ||||
| +++ b/sysdeps/unix/sysv/linux/x86/force-elision.h
 | ||||
| @@ -18,9 +18,45 @@
 | ||||
|   | ||||
|  /* Automatically enable elision for existing user lock kinds.  */ | ||||
|  #define FORCE_ELISION(m, s)						\ | ||||
| -  if (__pthread_force_elision						\
 | ||||
| -      && (m->__data.__kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)	\
 | ||||
| +  if (__pthread_force_elision)						\
 | ||||
|      {									\ | ||||
| -      mutex->__data.__kind |= PTHREAD_MUTEX_ELISION_NP;			\
 | ||||
| -      s;								\
 | ||||
| +      /* See concurrency notes regarding __kind in			\
 | ||||
| +	 struct __pthread_mutex_s in					\
 | ||||
| +	 sysdeps/nptl/bits/thread-shared-types.h.			\
 | ||||
| +									\
 | ||||
| +	 There are the following cases for the kind of a mutex		\
 | ||||
| +	 (The mask PTHREAD_MUTEX_ELISION_FLAGS_NP covers the flags	\
 | ||||
| +	 PTHREAD_MUTEX_ELISION_NP and PTHREAD_MUTEX_NO_ELISION_NP where	\
 | ||||
| +	 only one of both flags can be set):				\
 | ||||
| +	 - both flags are not set:					\
 | ||||
| +	 This is the first lock operation for this mutex.  Enable	\
 | ||||
| +	 elision as it is not enabled so far.				\
 | ||||
| +	 Note: It can happen that multiple threads are calling e.g.	\
 | ||||
| +	 pthread_mutex_lock at the same time as the first lock		\
 | ||||
| +	 operation for this mutex.  Then elision is enabled for this	\
 | ||||
| +	 mutex by multiple threads.  Storing with relaxed MO is enough	\
 | ||||
| +	 as all threads will store the same new value for the kind of	\
 | ||||
| +	 the mutex.  But we have to ensure that we always use the	\
 | ||||
| +	 elision path regardless if this thread has enabled elision or	\
 | ||||
| +	 another one.							\
 | ||||
| +									\
 | ||||
| +	 - PTHREAD_MUTEX_ELISION_NP flag is set:			\
 | ||||
| +	 Elision was already enabled for this mutex by a previous lock	\
 | ||||
| +	 operation.  See case above.  Just use the elision path.	\
 | ||||
| +									\
 | ||||
| +	 - PTHREAD_MUTEX_NO_ELISION_NP flag is set:			\
 | ||||
| +	 Elision was explicitly disabled by pthread_mutexattr_settype.	\
 | ||||
| +	 Do not use the elision path.					\
 | ||||
| +	 Note: The flag PTHREAD_MUTEX_NO_ELISION_NP will never be	\
 | ||||
| +	 changed after mutex initialization.  */			\
 | ||||
| +      int mutex_kind = atomic_load_relaxed (&((m)->__data.__kind));	\
 | ||||
| +      if ((mutex_kind & PTHREAD_MUTEX_ELISION_FLAGS_NP) == 0)		\
 | ||||
| +	{								\
 | ||||
| +	  mutex_kind |= PTHREAD_MUTEX_ELISION_NP;			\
 | ||||
| +	  atomic_store_relaxed (&((m)->__data.__kind), mutex_kind);	\
 | ||||
| +	}								\
 | ||||
| +      if ((mutex_kind & PTHREAD_MUTEX_ELISION_NP) != 0)			\
 | ||||
| +	{								\
 | ||||
| +	  s;								\
 | ||||
| +	}								\
 | ||||
|      } | ||||
							
								
								
									
										24
									
								
								SOURCES/glibc-rh1646379.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								SOURCES/glibc-rh1646379.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| commit bd3b0fbae33a9a4cc5e2daf049443d5cf03d4251 | ||||
| Author: Andreas Schwab <schwab@suse.de> | ||||
| Date:   Mon Nov 5 12:47:30 2018 +0100 | ||||
| 
 | ||||
|     libanl: properly cleanup if first helper thread creation failed (bug 22927) | ||||
| 
 | ||||
| diff --git a/resolv/gai_misc.c b/resolv/gai_misc.c
 | ||||
| index e7c3b63cc5725b4f..80a2cff8353fcb6c 100644
 | ||||
| --- a/resolv/gai_misc.c
 | ||||
| +++ b/resolv/gai_misc.c
 | ||||
| @@ -261,8 +261,11 @@ __gai_enqueue_request (struct gaicb *gaicbp)
 | ||||
|  	      /* We cannot create a thread in the moment and there is | ||||
|  		 also no thread running.  This is a problem.  `errno' is | ||||
|  		 set to EAGAIN if this is only a temporary problem.  */ | ||||
| -	      assert (lastp->next == newp);
 | ||||
| -	      lastp->next = NULL;
 | ||||
| +	      assert (requests == newp || lastp->next == newp);
 | ||||
| +	      if (lastp != NULL)
 | ||||
| +		lastp->next = NULL;
 | ||||
| +	      else
 | ||||
| +		requests = NULL;
 | ||||
|  	      requests_tail = lastp; | ||||
|   | ||||
|  	      newp->next = freelist; | ||||
							
								
								
									
										48
									
								
								SOURCES/glibc-rh1650560-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								SOURCES/glibc-rh1650560-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| commit 17b26500f9bb926d85e86821d014f7c1bb88043c | ||||
| Author: Joseph Myers <joseph@codesourcery.com> | ||||
| Date:   Mon Aug 13 21:35:27 2018 +0000 | ||||
| 
 | ||||
|     Update syscall-names.list for Linux 4.18. | ||||
|      | ||||
|     This patch updates sysdeps/unix/sysv/linux/syscall-names.list for | ||||
|     Linux 4.18.  The io_pgetevents and rseq syscalls are added to the | ||||
|     kernel on various architectures, so need to be mentioned in this file. | ||||
|      | ||||
|     Tested with build-many-glibcs.py. | ||||
|      | ||||
|             * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel | ||||
|             version to 4.18. | ||||
|             (io_pgetevents): New syscall. | ||||
|             (rseq): Likewise. | ||||
| 
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
 | ||||
| index 5306d538e6448163..9982a6334d46ae62 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/syscall-names.list
 | ||||
| +++ b/sysdeps/unix/sysv/linux/syscall-names.list
 | ||||
| @@ -22,8 +22,8 @@
 | ||||
|  # names are only used if the installed kernel headers also provide | ||||
|  # them. | ||||
|   | ||||
| -# The list of system calls is current as of Linux 4.17.
 | ||||
| -kernel 4.17
 | ||||
| +# The list of system calls is current as of Linux 4.18.
 | ||||
| +kernel 4.18
 | ||||
|   | ||||
|  FAST_atomic_update | ||||
|  FAST_cmpxchg | ||||
| @@ -186,6 +186,7 @@ inotify_rm_watch
 | ||||
|  io_cancel | ||||
|  io_destroy | ||||
|  io_getevents | ||||
| +io_pgetevents
 | ||||
|  io_setup | ||||
|  io_submit | ||||
|  ioctl | ||||
| @@ -431,6 +432,7 @@ renameat2
 | ||||
|  request_key | ||||
|  restart_syscall | ||||
|  rmdir | ||||
| +rseq
 | ||||
|  rt_sigaction | ||||
|  rt_sigpending | ||||
|  rt_sigprocmask | ||||
							
								
								
									
										30
									
								
								SOURCES/glibc-rh1650560-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								SOURCES/glibc-rh1650560-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| commit 029ad711b8ad4cf0e5d98e0c138a35a23a376a74 | ||||
| Author: Joseph Myers <joseph@codesourcery.com> | ||||
| Date:   Mon Oct 22 23:26:37 2018 +0000 | ||||
| 
 | ||||
|     Update kernel version in syscall-names.list to 4.19. | ||||
|      | ||||
|     Linux 4.19 does not add any new syscalls (some existing ones are added | ||||
|     to more architectures); this patch updates the version number in | ||||
|     syscall-names.list to reflect that it's still current for 4.19. | ||||
|      | ||||
|     Tested with build-many-glibcs.py. | ||||
|      | ||||
|             * sysdeps/unix/sysv/linux/syscall-names.list: Update kernel | ||||
|             version to 4.19. | ||||
| 
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/syscall-names.list b/sysdeps/unix/sysv/linux/syscall-names.list
 | ||||
| index 9982a6334d46ae62..f88001c9c38d5fc7 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/syscall-names.list
 | ||||
| +++ b/sysdeps/unix/sysv/linux/syscall-names.list
 | ||||
| @@ -22,8 +22,8 @@
 | ||||
|  # names are only used if the installed kernel headers also provide | ||||
|  # them. | ||||
|   | ||||
| -# The list of system calls is current as of Linux 4.18.
 | ||||
| -kernel 4.18
 | ||||
| +# The list of system calls is current as of Linux 4.19.
 | ||||
| +kernel 4.19
 | ||||
|   | ||||
|  FAST_atomic_update | ||||
|  FAST_cmpxchg | ||||
							
								
								
									
										127
									
								
								SOURCES/glibc-rh1650563.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										127
									
								
								SOURCES/glibc-rh1650563.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,127 @@ | ||||
| commit 745664bd798ec8fd50438605948eea594179fba1 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Aug 28 13:19:27 2018 +0200 | ||||
| 
 | ||||
|     nscd: Fix use-after-free in addgetnetgrentX [BZ #23520] | ||||
|      | ||||
|     addinnetgrX may use the heap-allocated buffer, so free the buffer | ||||
|     in this function. | ||||
| 
 | ||||
| diff --git a/nscd/netgroupcache.c b/nscd/netgroupcache.c
 | ||||
| index 2b35389cc816c3c8..87059fb28042f0a5 100644
 | ||||
| --- a/nscd/netgroupcache.c
 | ||||
| +++ b/nscd/netgroupcache.c
 | ||||
| @@ -113,7 +113,8 @@ do_notfound (struct database_dyn *db, int fd, request_header *req,
 | ||||
|  static time_t | ||||
|  addgetnetgrentX (struct database_dyn *db, int fd, request_header *req, | ||||
|  		 const char *key, uid_t uid, struct hashentry *he, | ||||
| -		 struct datahead *dh, struct dataset **resultp)
 | ||||
| +		 struct datahead *dh, struct dataset **resultp,
 | ||||
| +		 void **tofreep)
 | ||||
|  { | ||||
|    if (__glibc_unlikely (debug_level > 0)) | ||||
|      { | ||||
| @@ -139,6 +140,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|    size_t group_len = strlen (key) + 1; | ||||
|    struct name_list *first_needed | ||||
|      = alloca (sizeof (struct name_list) + group_len); | ||||
| +  *tofreep = NULL;
 | ||||
|   | ||||
|    if (netgroup_database == NULL | ||||
|        && __nss_database_lookup ("netgroup", NULL, NULL, &netgroup_database)) | ||||
| @@ -151,6 +153,7 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|   | ||||
|    memset (&data, '\0', sizeof (data)); | ||||
|    buffer = xmalloc (buflen); | ||||
| +  *tofreep = buffer;
 | ||||
|    first_needed->next = first_needed; | ||||
|    memcpy (first_needed->name, key, group_len); | ||||
|    data.needed_groups = first_needed; | ||||
| @@ -439,8 +442,6 @@ addgetnetgrentX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|      } | ||||
|   | ||||
|   out: | ||||
| -  free (buffer);
 | ||||
| -
 | ||||
|    *resultp = dataset; | ||||
|   | ||||
|    return timeout; | ||||
| @@ -477,8 +478,12 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|  							    group, group_len, | ||||
|  							    db, uid); | ||||
|    time_t timeout; | ||||
| +  void *tofree;
 | ||||
|    if (result != NULL) | ||||
| -    timeout = result->head.timeout;
 | ||||
| +    {
 | ||||
| +      timeout = result->head.timeout;
 | ||||
| +      tofree = NULL;
 | ||||
| +    }
 | ||||
|    else | ||||
|      { | ||||
|        request_header req_get = | ||||
| @@ -487,7 +492,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|  	  .key_len = group_len | ||||
|  	}; | ||||
|        timeout = addgetnetgrentX (db, -1, &req_get, group, uid, NULL, NULL, | ||||
| -				 &result);
 | ||||
| +				 &result, &tofree);
 | ||||
|      } | ||||
|   | ||||
|    struct indataset | ||||
| @@ -560,7 +565,7 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|        ++dh->nreloads; | ||||
|        if (cacheable) | ||||
|          pthread_rwlock_unlock (&db->lock); | ||||
| -      return timeout;
 | ||||
| +      goto out;
 | ||||
|      } | ||||
|   | ||||
|    if (he == NULL) | ||||
| @@ -596,17 +601,30 @@ addinnetgrX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|  	dh->usable = false; | ||||
|      } | ||||
|   | ||||
| + out:
 | ||||
| +  free (tofree);
 | ||||
|    return timeout; | ||||
|  } | ||||
|   | ||||
|   | ||||
| +static time_t
 | ||||
| +addgetnetgrentX_ignore (struct database_dyn *db, int fd, request_header *req,
 | ||||
| +			const char *key, uid_t uid, struct hashentry *he,
 | ||||
| +			struct datahead *dh)
 | ||||
| +{
 | ||||
| +  struct dataset *ignore;
 | ||||
| +  void *tofree;
 | ||||
| +  time_t timeout = addgetnetgrentX (db, fd, req, key, uid, he, dh,
 | ||||
| +				    &ignore, &tofree);
 | ||||
| +  free (tofree);
 | ||||
| +  return timeout;
 | ||||
| +}
 | ||||
| +
 | ||||
|  void | ||||
|  addgetnetgrent (struct database_dyn *db, int fd, request_header *req, | ||||
|  		void *key, uid_t uid) | ||||
|  { | ||||
| -  struct dataset *ignore;
 | ||||
| -
 | ||||
| -  addgetnetgrentX (db, fd, req, key, uid, NULL, NULL, &ignore);
 | ||||
| +  addgetnetgrentX_ignore (db, fd, req, key, uid, NULL, NULL);
 | ||||
|  } | ||||
|   | ||||
|   | ||||
| @@ -619,10 +637,8 @@ readdgetnetgrent (struct database_dyn *db, struct hashentry *he,
 | ||||
|        .type = GETNETGRENT, | ||||
|        .key_len = he->len | ||||
|      }; | ||||
| -  struct dataset *ignore;
 | ||||
| -
 | ||||
| -  return addgetnetgrentX (db, -1, &req, db->data + he->key, he->owner, he, dh,
 | ||||
| -			  &ignore);
 | ||||
| +  return addgetnetgrentX_ignore
 | ||||
| +    (db, -1, &req, db->data + he->key, he->owner, he, dh);
 | ||||
|  } | ||||
|   | ||||
|   | ||||
							
								
								
									
										234
									
								
								SOURCES/glibc-rh1650566.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								SOURCES/glibc-rh1650566.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,234 @@ | ||||
| commit a6e8926f8d49a213a9abb1a61f6af964f612ab7f | ||||
| Author: Paul Pluzhnikov <ppluzhnikov@google.com> | ||||
| Date:   Fri Aug 31 18:04:32 2018 -0700 | ||||
| 
 | ||||
|     [BZ #20271] Add newlines in __libc_fatal calls. | ||||
| 
 | ||||
| diff --git a/grp/initgroups.c b/grp/initgroups.c
 | ||||
| index f056fbf5aa6aa14c..93e7f5814da6286d 100644
 | ||||
| --- a/grp/initgroups.c
 | ||||
| +++ b/grp/initgroups.c
 | ||||
| @@ -128,7 +128,7 @@ internal_getgrouplist (const char *user, gid_t group, long int *size,
 | ||||
|   | ||||
|        /* This is really only for debugging.  */ | ||||
|        if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) | ||||
| -	__libc_fatal ("illegal status in internal_getgrouplist");
 | ||||
| +	__libc_fatal ("Illegal status in internal_getgrouplist.\n");
 | ||||
|   | ||||
|        /* For compatibility reason we will continue to look for more | ||||
|  	 entries using the next service even though data has already | ||||
| diff --git a/include/stdio.h b/include/stdio.h
 | ||||
| index 9162d4e24717e31a..7a5c09089fc4d348 100644
 | ||||
| --- a/include/stdio.h
 | ||||
| +++ b/include/stdio.h
 | ||||
| @@ -98,7 +98,8 @@ enum __libc_message_action
 | ||||
|    do_backtrace	= 1 << 1	/* Backtrace.  */ | ||||
|  }; | ||||
|   | ||||
| -/* Print out MESSAGE on the error output and abort.  */
 | ||||
| +/* Print out MESSAGE (which should end with a newline) on the error output
 | ||||
| +   and abort.  */
 | ||||
|  extern void __libc_fatal (const char *__message) | ||||
|       __attribute__ ((__noreturn__)); | ||||
|  extern void __libc_message (enum __libc_message_action action, | ||||
| diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c
 | ||||
| index 3e1105418210288e..ebf07ca82d87de7d 100644
 | ||||
| --- a/nptl/pthread_cond_wait.c
 | ||||
| +++ b/nptl/pthread_cond_wait.c
 | ||||
| @@ -516,7 +516,7 @@ __pthread_cond_wait_common (pthread_cond_t *cond, pthread_mutex_t *mutex,
 | ||||
|  		  struct timespec rt; | ||||
|  		  if (__clock_gettime (CLOCK_MONOTONIC, &rt) != 0) | ||||
|  		    __libc_fatal ("clock_gettime does not support " | ||||
| -				  "CLOCK_MONOTONIC");
 | ||||
| +				  "CLOCK_MONOTONIC\n");
 | ||||
|  		  /* Convert the absolute timeout value to a relative | ||||
|  		     timeout.  */ | ||||
|  		  rt.tv_sec = abstime->tv_sec - rt.tv_sec; | ||||
| diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c
 | ||||
| index 2c74951f579f4afd..4764f14a45f68e0a 100644
 | ||||
| --- a/nscd/initgrcache.c
 | ||||
| +++ b/nscd/initgrcache.c
 | ||||
| @@ -159,7 +159,7 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
 | ||||
|   | ||||
|        /* This is really only for debugging.  */ | ||||
|        if (NSS_STATUS_TRYAGAIN > status || status > NSS_STATUS_RETURN) | ||||
| -	__libc_fatal ("illegal status in internal_getgrouplist");
 | ||||
| +	__libc_fatal ("Illegal status in internal_getgrouplist.\n");
 | ||||
|   | ||||
|        any_success |= status == NSS_STATUS_SUCCESS; | ||||
|   | ||||
| diff --git a/nss/nsswitch.c b/nss/nsswitch.c
 | ||||
| index ee46f24424bc1ca2..3c48b4b85e881cdb 100644
 | ||||
| --- a/nss/nsswitch.c
 | ||||
| +++ b/nss/nsswitch.c
 | ||||
| @@ -235,7 +235,7 @@ __nss_next2 (service_user **ni, const char *fct_name, const char *fct2_name,
 | ||||
|        /* This is really only for debugging.  */ | ||||
|        if (__builtin_expect (NSS_STATUS_TRYAGAIN > status | ||||
|  			    || status > NSS_STATUS_RETURN, 0)) | ||||
| -	 __libc_fatal ("illegal status in __nss_next");
 | ||||
| +	 __libc_fatal ("Illegal status in __nss_next.\n");
 | ||||
|   | ||||
|         if (nss_next_action (*ni, status) == NSS_ACTION_RETURN) | ||||
|  	 return 1; | ||||
| diff --git a/sysdeps/aarch64/dl-irel.h b/sysdeps/aarch64/dl-irel.h
 | ||||
| index 5889ee187b7a1eaf..bef71ed0f31a6387 100644
 | ||||
| --- a/sysdeps/aarch64/dl-irel.h
 | ||||
| +++ b/sysdeps/aarch64/dl-irel.h
 | ||||
| @@ -47,7 +47,7 @@ elf_irela (const ElfW(Rela) *reloc)
 | ||||
|        *reloc_addr = value; | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif | ||||
| diff --git a/sysdeps/arm/dl-irel.h b/sysdeps/arm/dl-irel.h
 | ||||
| index a7b6456075659baf..be6eb7743eb5f08d 100644
 | ||||
| --- a/sysdeps/arm/dl-irel.h
 | ||||
| +++ b/sysdeps/arm/dl-irel.h
 | ||||
| @@ -46,7 +46,7 @@ elf_irel (const Elf32_Rel *reloc)
 | ||||
|        *reloc_addr = value; | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/generic/unwind-dw2.c b/sysdeps/generic/unwind-dw2.c
 | ||||
| index 082609b34a3f773b..724c16a7f0bf465b 100644
 | ||||
| --- a/sysdeps/generic/unwind-dw2.c
 | ||||
| +++ b/sysdeps/generic/unwind-dw2.c
 | ||||
| @@ -843,7 +843,7 @@ execute_cfa_program (const unsigned char *insn_ptr,
 | ||||
|  	    struct frame_state_reg_info *old_rs = fs->regs.prev; | ||||
|  #ifdef _LIBC | ||||
|  	    if (old_rs == NULL) | ||||
| -	      __libc_fatal ("invalid DWARF unwind data");
 | ||||
| +	      __libc_fatal ("Invalid DWARF unwind data.\n");
 | ||||
|  	    else | ||||
|  #endif | ||||
|  	      { | ||||
| diff --git a/sysdeps/i386/dl-irel.h b/sysdeps/i386/dl-irel.h
 | ||||
| index 55303180c7aca495..bcaf0668acf8e2f2 100644
 | ||||
| --- a/sysdeps/i386/dl-irel.h
 | ||||
| +++ b/sysdeps/i386/dl-irel.h
 | ||||
| @@ -45,7 +45,7 @@ elf_irel (const Elf32_Rel *reloc)
 | ||||
|        *reloc_addr = value; | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/nptl/futex-internal.h b/sysdeps/nptl/futex-internal.h
 | ||||
| index 1a5624789d4ab117..6fd27f0df6c27b69 100644
 | ||||
| --- a/sysdeps/nptl/futex-internal.h
 | ||||
| +++ b/sysdeps/nptl/futex-internal.h
 | ||||
| @@ -197,7 +197,7 @@ futex_wake (unsigned int* futex_word, int processes_to_wake, int private);
 | ||||
|  static __always_inline __attribute__ ((__noreturn__)) void | ||||
|  futex_fatal_error (void) | ||||
|  { | ||||
| -  __libc_fatal ("The futex facility returned an unexpected error code.");
 | ||||
| +  __libc_fatal ("The futex facility returned an unexpected error code.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif  /* futex-internal.h */ | ||||
| diff --git a/sysdeps/powerpc/powerpc32/dl-irel.h b/sysdeps/powerpc/powerpc32/dl-irel.h
 | ||||
| index a7368b25829618cb..61d0e4cf61ec45d3 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc32/dl-irel.h
 | ||||
| +++ b/sysdeps/powerpc/powerpc32/dl-irel.h
 | ||||
| @@ -46,7 +46,7 @@ elf_irela (const Elf32_Rela *reloc)
 | ||||
|        *reloc_addr = value; | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/powerpc/powerpc64/dl-irel.h b/sysdeps/powerpc/powerpc64/dl-irel.h
 | ||||
| index ab13c04358868270..2fd0ee8a86e85ba0 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc64/dl-irel.h
 | ||||
| +++ b/sysdeps/powerpc/powerpc64/dl-irel.h
 | ||||
| @@ -57,7 +57,7 @@ elf_irela (const Elf64_Rela *reloc)
 | ||||
|  #endif | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/s390/dl-irel.h b/sysdeps/s390/dl-irel.h
 | ||||
| index d8ba7ba42709f45c..ecb24f0a9be0daa7 100644
 | ||||
| --- a/sysdeps/s390/dl-irel.h
 | ||||
| +++ b/sysdeps/s390/dl-irel.h
 | ||||
| @@ -46,7 +46,7 @@ elf_irela (const ElfW(Rela) *reloc)
 | ||||
|        *reloc_addr = value; | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/sparc/sparc32/dl-irel.h b/sysdeps/sparc/sparc32/dl-irel.h
 | ||||
| index ffca36864f24d1fb..cf47cda8345b1a39 100644
 | ||||
| --- a/sysdeps/sparc/sparc32/dl-irel.h
 | ||||
| +++ b/sysdeps/sparc/sparc32/dl-irel.h
 | ||||
| @@ -56,7 +56,7 @@ elf_irela (const Elf32_Rela *reloc)
 | ||||
|    else if (r_type == R_SPARC_NONE) | ||||
|      ; | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/sparc/sparc64/dl-irel.h b/sysdeps/sparc/sparc64/dl-irel.h
 | ||||
| index c5cd3057aca1baf6..446fed18365cfd13 100644
 | ||||
| --- a/sysdeps/sparc/sparc64/dl-irel.h
 | ||||
| +++ b/sysdeps/sparc/sparc64/dl-irel.h
 | ||||
| @@ -59,7 +59,7 @@ elf_irela (const Elf64_Rela *reloc)
 | ||||
|    else if (r_type == R_SPARC_NONE) | ||||
|      ; | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
| diff --git a/sysdeps/unix/sysv/linux/netlink_assert_response.c b/sysdeps/unix/sysv/linux/netlink_assert_response.c
 | ||||
| index f31ccb52ffa56436..6afc3a17ced18e1c 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/netlink_assert_response.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/netlink_assert_response.c
 | ||||
| @@ -72,12 +72,12 @@ __netlink_assert_response (int fd, ssize_t result)
 | ||||
|            char message[200]; | ||||
|            if (family < 0) | ||||
|              __snprintf (message, sizeof (message), | ||||
| -                        "Unexpected error %d on netlink descriptor %d",
 | ||||
| +                        "Unexpected error %d on netlink descriptor %d.\n",
 | ||||
|                          error_code, fd); | ||||
|            else | ||||
|              __snprintf (message, sizeof (message), | ||||
|                          "Unexpected error %d on netlink descriptor %d" | ||||
| -                        " (address family %d)",
 | ||||
| +                        " (address family %d).\n",
 | ||||
|                          error_code, fd, family); | ||||
|            __libc_fatal (message); | ||||
|          } | ||||
| diff --git a/sysdeps/x86_64/dl-irel.h b/sysdeps/x86_64/dl-irel.h
 | ||||
| index 6ecc50fb42333c19..33f100d8b1781ea7 100644
 | ||||
| --- a/sysdeps/x86_64/dl-irel.h
 | ||||
| +++ b/sysdeps/x86_64/dl-irel.h
 | ||||
| @@ -45,7 +45,7 @@ elf_irela (const ElfW(Rela) *reloc)
 | ||||
|        *reloc_addr = value; | ||||
|      } | ||||
|    else | ||||
| -    __libc_fatal ("unexpected reloc type in static binary");
 | ||||
| +    __libc_fatal ("Unexpected reloc type in static binary.\n");
 | ||||
|  } | ||||
|   | ||||
|  #endif /* dl-irel.h */ | ||||
							
								
								
									
										24
									
								
								SOURCES/glibc-rh1650571.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								SOURCES/glibc-rh1650571.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | ||||
| commit e4e4fde51a309801af5eed72d3494cbf4b7737aa | ||||
| Author: Paul Eggert <eggert@cs.ucla.edu> | ||||
| Date:   Tue Sep 18 15:02:10 2018 -0700 | ||||
| 
 | ||||
|     Fix tzfile low-memory assertion failure | ||||
|      | ||||
|     [BZ #21716] | ||||
|     * time/tzfile.c (__tzfile_read): Check for memory exhaustion | ||||
|     when registering time zone abbreviations. | ||||
| 
 | ||||
| diff --git a/time/tzfile.c b/time/tzfile.c
 | ||||
| index 2a385b92bcdefec0..ea6e94030392fc75 100644
 | ||||
| --- a/time/tzfile.c
 | ||||
| +++ b/time/tzfile.c
 | ||||
| @@ -410,7 +410,8 @@ __tzfile_read (const char *file, size_t extra, char **extrap)
 | ||||
|   | ||||
|    /* First "register" all timezone names.  */ | ||||
|    for (i = 0; i < num_types; ++i) | ||||
| -    (void) __tzstring (&zone_names[types[i].idx]);
 | ||||
| +    if (__tzstring (&zone_names[types[i].idx]) == NULL)
 | ||||
| +      goto ret_free_transitions;
 | ||||
|   | ||||
|    /* Find the standard and daylight time offsets used by the rule file. | ||||
|       We choose the offsets in the types of each flavor that are | ||||
							
								
								
									
										70
									
								
								SOURCES/glibc-rh1651274.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								SOURCES/glibc-rh1651274.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,70 @@ | ||||
| commit 35e3fbc4512c880fccb35b8e3abd132d4be18480 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Nov 19 15:35:03 2018 +0100 | ||||
| 
 | ||||
|     support: Print timestamps in timeout handler | ||||
|      | ||||
|     This is sometimes useful to determine if a test truly got stuck, or if | ||||
|     it was making progress (logging information to standard output) and | ||||
|     was merely slow to finish. | ||||
| 
 | ||||
| diff --git a/support/support_test_main.c b/support/support_test_main.c
 | ||||
| index 23429779aca85613..fa3c2e06dee5ae0f 100644
 | ||||
| --- a/support/support_test_main.c
 | ||||
| +++ b/support/support_test_main.c
 | ||||
| @@ -30,6 +30,7 @@
 | ||||
|  #include <string.h> | ||||
|  #include <sys/param.h> | ||||
|  #include <sys/resource.h> | ||||
| +#include <sys/time.h>
 | ||||
|  #include <sys/types.h> | ||||
|  #include <sys/wait.h> | ||||
|  #include <time.h> | ||||
| @@ -86,6 +87,19 @@ static pid_t test_pid;
 | ||||
|  /* The cleanup handler passed to test_main.  */ | ||||
|  static void (*cleanup_function) (void); | ||||
|   | ||||
| +static void
 | ||||
| +print_timestamp (const char *what, struct timeval tv)
 | ||||
| +{
 | ||||
| +  struct tm tm;
 | ||||
| +  if (gmtime_r (&tv.tv_sec, &tm) == NULL)
 | ||||
| +    printf ("%s: %lld.%06d\n",
 | ||||
| +            what, (long long int) tv.tv_sec, (int) tv.tv_usec);
 | ||||
| +  else
 | ||||
| +    printf ("%s: %04d-%02d-%02dT%02d:%02d:%02d.%06d\n",
 | ||||
| +            what, 1900 + tm.tm_year, tm.tm_mon + 1, tm.tm_mday,
 | ||||
| +            tm.tm_hour, tm.tm_min, tm.tm_sec, (int) tv.tv_usec);
 | ||||
| +}
 | ||||
| +
 | ||||
|  /* Timeout handler.  We kill the child and exit with an error.  */ | ||||
|  static void | ||||
|  __attribute__ ((noreturn)) | ||||
| @@ -94,6 +108,13 @@ signal_handler (int sig)
 | ||||
|    int killed; | ||||
|    int status; | ||||
|   | ||||
| +  /* Do this first to avoid further interference from the
 | ||||
| +     subprocess.  */
 | ||||
| +  struct timeval now;
 | ||||
| +  bool now_available = gettimeofday (&now, NULL) == 0;
 | ||||
| +  struct stat64 st;
 | ||||
| +  bool st_available = fstat64 (STDOUT_FILENO, &st) == 0 && st.st_mtime != 0;
 | ||||
| +
 | ||||
|    assert (test_pid > 1); | ||||
|    /* Kill the whole process group.  */ | ||||
|    kill (-test_pid, SIGKILL); | ||||
| @@ -144,6 +165,13 @@ signal_handler (int sig)
 | ||||
|      printf ("Timed out: killed the child process but it exited %d\n", | ||||
|              WEXITSTATUS (status)); | ||||
|   | ||||
| +  if (now_available)
 | ||||
| +    print_timestamp ("Termination time", now);
 | ||||
| +  if (st_available)
 | ||||
| +    print_timestamp ("Last write to standard output",
 | ||||
| +                     (struct timeval) { st.st_mtim.tv_sec,
 | ||||
| +                         st.st_mtim.tv_nsec / 1000 });
 | ||||
| +
 | ||||
|    /* Exit with an error.  */ | ||||
|    exit (1); | ||||
|  } | ||||
							
								
								
									
										31
									
								
								SOURCES/glibc-rh1651283-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/glibc-rh1651283-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| commit d6db68e66dff25d12c3bc5641b60cbd7fb6ab44f | ||||
| Author: Moritz Eckert <m.eckert@cs.ucsb.edu> | ||||
| Date:   Thu Aug 16 21:08:36 2018 -0400 | ||||
| 
 | ||||
|     malloc: Mitigate null-byte overflow attacks | ||||
|      | ||||
|     * malloc/malloc.c (_int_free): Check for corrupt prev_size vs size. | ||||
|     (malloc_consolidate): Likewise. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index 13c52f376859562d..e450597e2e527fb7 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -4306,6 +4306,8 @@ _int_free (mstate av, mchunkptr p, int have_lock)
 | ||||
|        prevsize = prev_size (p); | ||||
|        size += prevsize; | ||||
|        p = chunk_at_offset(p, -((long) prevsize)); | ||||
| +      if (__glibc_unlikely (chunksize(p) != prevsize))
 | ||||
| +        malloc_printerr ("corrupted size vs. prev_size while consolidating");
 | ||||
|        unlink(av, p, bck, fwd); | ||||
|      } | ||||
|   | ||||
| @@ -4467,6 +4469,8 @@ static void malloc_consolidate(mstate av)
 | ||||
|  	  prevsize = prev_size (p); | ||||
|  	  size += prevsize; | ||||
|  	  p = chunk_at_offset(p, -((long) prevsize)); | ||||
| +	  if (__glibc_unlikely (chunksize(p) != prevsize))
 | ||||
| +	    malloc_printerr ("corrupted size vs. prev_size in fastbins");
 | ||||
|  	  unlink(av, p, bck, fwd); | ||||
|  	} | ||||
|   | ||||
							
								
								
									
										30
									
								
								SOURCES/glibc-rh1651283-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								SOURCES/glibc-rh1651283-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,30 @@ | ||||
| commit 30a17d8c95fbfb15c52d1115803b63aaa73a285c | ||||
| Author: Pochang Chen <johnchen902@gmail.com> | ||||
| Date:   Thu Aug 16 15:24:24 2018 -0400 | ||||
| 
 | ||||
|     malloc: Verify size of top chunk. | ||||
|      | ||||
|     The House of Force is a well-known technique to exploit heap | ||||
|     overflow. In essence, this exploit takes three steps: | ||||
|     1. Overwrite the size of top chunk with very large value (e.g. -1). | ||||
|     2. Request x bytes from top chunk. As the size of top chunk | ||||
|        is corrupted, x can be arbitrarily large and top chunk will | ||||
|        still be offset by x. | ||||
|     3. The next allocation from top chunk will thus be controllable. | ||||
|      | ||||
|     If we verify the size of top chunk at step 2, we can stop such attack. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index e450597e2e527fb7..d8d4581a9dcea80a 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -4084,6 +4084,9 @@ _int_malloc (mstate av, size_t bytes)
 | ||||
|        victim = av->top; | ||||
|        size = chunksize (victim); | ||||
|   | ||||
| +      if (__glibc_unlikely (size > av->system_mem))
 | ||||
| +        malloc_printerr ("malloc(): corrupted top size");
 | ||||
| +
 | ||||
|        if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) | ||||
|          { | ||||
|            remainder_size = size - nb; | ||||
							
								
								
									
										122
									
								
								SOURCES/glibc-rh1651283-3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								SOURCES/glibc-rh1651283-3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,122 @@ | ||||
| commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c | ||||
| Author: Istvan Kurucsai <pistukem@gmail.com> | ||||
| Date:   Tue Jan 16 14:54:32 2018 +0100 | ||||
| 
 | ||||
|     malloc: Additional checks for unsorted bin integrity I. | ||||
|      | ||||
|     On Thu, Jan 11, 2018 at 3:50 PM, Florian Weimer <fweimer@redhat.com> wrote: | ||||
|     > On 11/07/2017 04:27 PM, Istvan Kurucsai wrote: | ||||
|     >> | ||||
|     >> +          next = chunk_at_offset (victim, size); | ||||
|     > | ||||
|     > | ||||
|     > For new code, we prefer declarations with initializers. | ||||
|      | ||||
|     Noted. | ||||
|      | ||||
|     >> +          if (__glibc_unlikely (chunksize_nomask (victim) <= 2 * SIZE_SZ) | ||||
|     >> +              || __glibc_unlikely (chunksize_nomask (victim) > | ||||
|     >> av->system_mem)) | ||||
|     >> +            malloc_printerr("malloc(): invalid size (unsorted)"); | ||||
|     >> +          if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ) | ||||
|     >> +              || __glibc_unlikely (chunksize_nomask (next) > | ||||
|     >> av->system_mem)) | ||||
|     >> +            malloc_printerr("malloc(): invalid next size (unsorted)"); | ||||
|     >> +          if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != | ||||
|     >> size)) | ||||
|     >> +            malloc_printerr("malloc(): mismatching next->prev_size | ||||
|     >> (unsorted)"); | ||||
|     > | ||||
|     > | ||||
|     > I think this check is redundant because prev_size (next) and chunksize | ||||
|     > (victim) are loaded from the same memory location. | ||||
|      | ||||
|     I'm fairly certain that it compares mchunk_size of victim against | ||||
|     mchunk_prev_size of the next chunk, i.e. the size of victim in its | ||||
|     header and footer. | ||||
|      | ||||
|     >> +          if (__glibc_unlikely (bck->fd != victim) | ||||
|     >> +              || __glibc_unlikely (victim->fd != unsorted_chunks (av))) | ||||
|     >> +            malloc_printerr("malloc(): unsorted double linked list | ||||
|     >> corrupted"); | ||||
|     >> +          if (__glibc_unlikely (prev_inuse(next))) | ||||
|     >> +            malloc_printerr("malloc(): invalid next->prev_inuse | ||||
|     >> (unsorted)"); | ||||
|     > | ||||
|     > | ||||
|     > There's a missing space after malloc_printerr. | ||||
|      | ||||
|     Noted. | ||||
|      | ||||
|     > Why do you keep using chunksize_nomask?  We never investigated why the | ||||
|     > original code uses it.  It may have been an accident. | ||||
|      | ||||
|     You are right, I don't think it makes a difference in these checks. So | ||||
|     the size local can be reused for the checks against victim. For next, | ||||
|     leaving it as such avoids the masking operation. | ||||
|      | ||||
|     > Again, for non-main arenas, the checks against av->system_mem could be made | ||||
|     > tighter (against the heap size).  Maybe you could put the condition into a | ||||
|     > separate inline function? | ||||
|      | ||||
|     We could also do a chunk boundary check similar to what I proposed in | ||||
|     the thread for the first patch in the series to be even more strict. | ||||
|     I'll gladly try to implement either but believe that refining these | ||||
|     checks would bring less benefits than in the case of the top chunk. | ||||
|     Intra-arena or intra-heap overlaps would still be doable here with | ||||
|     unsorted chunks and I don't see any way to counter that besides more | ||||
|     generic measures like randomizing allocations and your metadata | ||||
|     encoding patches. | ||||
|      | ||||
|     I've attached a revised version with the above comments incorporated | ||||
|     but without the refined checks. | ||||
|      | ||||
|     Thanks, | ||||
|     Istvan | ||||
|      | ||||
|     From a12d5d40fd7aed5fa10fc444dcb819947b72b315 Mon Sep 17 00:00:00 2001 | ||||
|     From: Istvan Kurucsai <pistukem@gmail.com> | ||||
|     Date: Tue, 16 Jan 2018 14:48:16 +0100 | ||||
|     Subject: [PATCH v2 1/1] malloc: Additional checks for unsorted bin integrity | ||||
|      I. | ||||
|      | ||||
|     Ensure the following properties of chunks encountered during binning: | ||||
|     - victim chunk has reasonable size | ||||
|     - next chunk has reasonable size | ||||
|     - next->prev_size == victim->size | ||||
|     - valid double linked list | ||||
|     - PREV_INUSE of next chunk is unset | ||||
|      | ||||
|         * malloc/malloc.c (_int_malloc): Additional binning code checks. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index d8d4581a9dcea80a..dad0e73735789530 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -3724,11 +3724,22 @@ _int_malloc (mstate av, size_t bytes)
 | ||||
|        while ((victim = unsorted_chunks (av)->bk) != unsorted_chunks (av)) | ||||
|          { | ||||
|            bck = victim->bk; | ||||
| -          if (__builtin_expect (chunksize_nomask (victim) <= 2 * SIZE_SZ, 0)
 | ||||
| -              || __builtin_expect (chunksize_nomask (victim)
 | ||||
| -				   > av->system_mem, 0))
 | ||||
| -            malloc_printerr ("malloc(): memory corruption");
 | ||||
|            size = chunksize (victim); | ||||
| +          mchunkptr next = chunk_at_offset (victim, size);
 | ||||
| +
 | ||||
| +          if (__glibc_unlikely (size <= 2 * SIZE_SZ)
 | ||||
| +              || __glibc_unlikely (size > av->system_mem))
 | ||||
| +            malloc_printerr ("malloc(): invalid size (unsorted)");
 | ||||
| +          if (__glibc_unlikely (chunksize_nomask (next) < 2 * SIZE_SZ)
 | ||||
| +              || __glibc_unlikely (chunksize_nomask (next) > av->system_mem))
 | ||||
| +            malloc_printerr ("malloc(): invalid next size (unsorted)");
 | ||||
| +          if (__glibc_unlikely ((prev_size (next) & ~(SIZE_BITS)) != size))
 | ||||
| +            malloc_printerr ("malloc(): mismatching next->prev_size (unsorted)");
 | ||||
| +          if (__glibc_unlikely (bck->fd != victim)
 | ||||
| +              || __glibc_unlikely (victim->fd != unsorted_chunks (av)))
 | ||||
| +            malloc_printerr ("malloc(): unsorted double linked list corrupted");
 | ||||
| +          if (__glibc_unlikely (prev_inuse(next)))
 | ||||
| +            malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)");
 | ||||
|   | ||||
|            /* | ||||
|               If a small request, try to use last remainder if it is the | ||||
							
								
								
									
										26
									
								
								SOURCES/glibc-rh1651283-4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								SOURCES/glibc-rh1651283-4.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| The below commit contains only a whitespace change and was backported in | ||||
| order to avoid future conflicts. | ||||
| 
 | ||||
| commit 35cfefd96062145eeb8aee6bd72d07e0909a6b2e | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Mon Aug 20 14:57:13 2018 +0200 | ||||
| 
 | ||||
|     malloc: Add ChangeLog for accidentally committed change | ||||
|      | ||||
|     Commit b90ddd08f6dd688e651df9ee89ca3a69ff88cd0c ("malloc: Additional | ||||
|     checks for unsorted bin integrity I.") was committed without a | ||||
|     whitespace fix, so it is adjusted here as well. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index c07463001a65af90..eb6a8ff33c0c313b 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -3745,7 +3745,7 @@ _int_malloc (mstate av, size_t bytes)
 | ||||
|            if (__glibc_unlikely (bck->fd != victim) | ||||
|                || __glibc_unlikely (victim->fd != unsorted_chunks (av))) | ||||
|              malloc_printerr ("malloc(): unsorted double linked list corrupted"); | ||||
| -          if (__glibc_unlikely (prev_inuse(next)))
 | ||||
| +          if (__glibc_unlikely (prev_inuse (next)))
 | ||||
|              malloc_printerr ("malloc(): invalid next->prev_inuse (unsorted)"); | ||||
|   | ||||
|            /* | ||||
							
								
								
									
										38
									
								
								SOURCES/glibc-rh1651283-5.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								SOURCES/glibc-rh1651283-5.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| commit ebe544bf6e8eec35e754fd49efb027c6f161b6cb | ||||
| Author: Istvan Kurucsai <pistukem@gmail.com> | ||||
| Date:   Thu Dec 20 23:30:07 2018 -0500 | ||||
| 
 | ||||
|     malloc: Add more integrity checks to mremap_chunk. | ||||
|      | ||||
|     * malloc/malloc.c (mremap_chunk): Additional checks. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index eb6a8ff33c0c313b..4df5cb4862a7b854 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -2856,16 +2856,22 @@ mremap_chunk (mchunkptr p, size_t new_size)
 | ||||
|    char *cp; | ||||
|   | ||||
|    assert (chunk_is_mmapped (p)); | ||||
| -  assert (((size + offset) & (GLRO (dl_pagesize) - 1)) == 0);
 | ||||
| +
 | ||||
| +  uintptr_t block = (uintptr_t) p - offset;
 | ||||
| +  uintptr_t mem = (uintptr_t) chunk2mem(p);
 | ||||
| +  size_t total_size = offset + size;
 | ||||
| +  if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0
 | ||||
| +      || __glibc_unlikely (!powerof2 (mem & (pagesize - 1))))
 | ||||
| +    malloc_printerr("mremap_chunk(): invalid pointer");
 | ||||
|   | ||||
|    /* Note the extra SIZE_SZ overhead as in mmap_chunk(). */ | ||||
|    new_size = ALIGN_UP (new_size + offset + SIZE_SZ, pagesize); | ||||
|   | ||||
|    /* No need to remap if the number of pages does not change.  */ | ||||
| -  if (size + offset == new_size)
 | ||||
| +  if (total_size == new_size)
 | ||||
|      return p; | ||||
|   | ||||
| -  cp = (char *) __mremap ((char *) p - offset, size + offset, new_size,
 | ||||
| +  cp = (char *) __mremap ((char *) block, total_size, new_size,
 | ||||
|                            MREMAP_MAYMOVE); | ||||
|   | ||||
|    if (cp == MAP_FAILED) | ||||
							
								
								
									
										38
									
								
								SOURCES/glibc-rh1651283-6.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								SOURCES/glibc-rh1651283-6.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,38 @@ | ||||
| commit c0e82f117357a941e4d40fcc08babbd6a3c3a1b5 | ||||
| Author: Istvan Kurucsai <pistukem@gmail.com> | ||||
| Date:   Fri Dec 21 00:13:01 2018 -0500 | ||||
| 
 | ||||
|     malloc: Check the alignment of mmapped chunks before unmapping. | ||||
|      | ||||
|     * malloc/malloc.c (munmap_chunk): Verify chunk alignment. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index 4df5cb4862a7b854..4412a4ffc83b013b 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -2817,6 +2817,7 @@ systrim (size_t pad, mstate av)
 | ||||
|  static void | ||||
|  munmap_chunk (mchunkptr p) | ||||
|  { | ||||
| +  size_t pagesize = GLRO (dl_pagesize);
 | ||||
|    INTERNAL_SIZE_T size = chunksize (p); | ||||
|   | ||||
|    assert (chunk_is_mmapped (p)); | ||||
| @@ -2826,6 +2827,7 @@ munmap_chunk (mchunkptr p)
 | ||||
|    if (DUMPED_MAIN_ARENA_CHUNK (p)) | ||||
|      return; | ||||
|   | ||||
| +  uintptr_t mem = (uintptr_t) chunk2mem (p);
 | ||||
|    uintptr_t block = (uintptr_t) p - prev_size (p); | ||||
|    size_t total_size = prev_size (p) + size; | ||||
|    /* Unfortunately we have to do the compilers job by hand here.  Normally | ||||
| @@ -2833,7 +2835,8 @@ munmap_chunk (mchunkptr p)
 | ||||
|       page size.  But gcc does not recognize the optimization possibility | ||||
|       (in the moment at least) so we combine the two values into one before | ||||
|       the bit test.  */ | ||||
| -  if (__builtin_expect (((block | total_size) & (GLRO (dl_pagesize) - 1)) != 0, 0))
 | ||||
| +  if (__glibc_unlikely ((block | total_size) & (pagesize - 1)) != 0
 | ||||
| +      || __glibc_unlikely (!powerof2 (mem & (pagesize - 1))))
 | ||||
|      malloc_printerr ("munmap_chunk(): invalid pointer"); | ||||
|   | ||||
|    atomic_decrement (&mp_.n_mmaps); | ||||
							
								
								
									
										31
									
								
								SOURCES/glibc-rh1651283-7.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								SOURCES/glibc-rh1651283-7.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,31 @@ | ||||
| commit 5b06f538c5aee0389ed034f60d90a8884d6d54de | ||||
| Author: Adam Maris <amaris@redhat.com> | ||||
| Date:   Thu Mar 14 16:51:16 2019 -0400 | ||||
| 
 | ||||
|     malloc: Check for large bin list corruption when inserting unsorted chunk | ||||
|      | ||||
|     Fixes bug 24216. This patch adds security checks for bk and bk_nextsize pointers | ||||
|     of chunks in large bin when inserting chunk from unsorted bin. It was possible | ||||
|     to write the pointer to victim (newly inserted chunk) to arbitrary memory | ||||
|     locations if bk or bk_nextsize pointers of the next large bin chunk | ||||
|     got corrupted. | ||||
| 
 | ||||
| diff --git a/malloc/malloc.c b/malloc/malloc.c
 | ||||
| index 4412a4ffc83b013b..723d393f529bdb4c 100644
 | ||||
| --- a/malloc/malloc.c
 | ||||
| +++ b/malloc/malloc.c
 | ||||
| @@ -3876,10 +3876,14 @@ _int_malloc (mstate av, size_t bytes)
 | ||||
|                          { | ||||
|                            victim->fd_nextsize = fwd; | ||||
|                            victim->bk_nextsize = fwd->bk_nextsize; | ||||
| +                          if (__glibc_unlikely (fwd->bk_nextsize->fd_nextsize != fwd))
 | ||||
| +                            malloc_printerr ("malloc(): largebin double linked list corrupted (nextsize)");
 | ||||
|                            fwd->bk_nextsize = victim; | ||||
|                            victim->bk_nextsize->fd_nextsize = victim; | ||||
|                          } | ||||
|                        bck = fwd->bk; | ||||
| +                      if (bck->fd != fwd)
 | ||||
| +                        malloc_printerr ("malloc(): largebin double linked list corrupted (bk)");
 | ||||
|                      } | ||||
|                  } | ||||
|                else | ||||
							
								
								
									
										307
									
								
								SOURCES/glibc-rh1651742.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										307
									
								
								SOURCES/glibc-rh1651742.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,307 @@ | ||||
| commit f0458cf4f9ff3d870c43b624e6dccaaf657d5e83 | ||||
| Author: Adhemerval Zanella <adhemerval.zanella@linaro.org> | ||||
| Date:   Mon Aug 27 09:42:50 2018 -0300 | ||||
| 
 | ||||
|     powerpc: Only enable TLE with PPC_FEATURE2_HTM_NOSC | ||||
|      | ||||
|     Linux from 3.9 through 4.2 does not abort HTM transaction on syscalls, | ||||
|     instead it suspend and resume it when leaving the kernel.  The | ||||
|     side-effects of the syscall will always remain visible, even if the | ||||
|     transaction is aborted.  This is an issue when transaction is used along | ||||
|     with futex syscall, on pthread_cond_wait for instance, where the futex | ||||
|     call might succeed but the transaction is rolled back leading the | ||||
|     pthread_cond object in an inconsistent state. | ||||
|      | ||||
|     Glibc used to prevent it by always aborting a transaction before issuing | ||||
|     a syscall.  Linux 4.2 also decided to abort active transaction in | ||||
|     syscalls which makes the glibc workaround superfluous.  Worse, glibc | ||||
|     transaction abortion leads to a performance issue on recent kernels | ||||
|     where the HTM state is saved/restore lazily (v4.9).  By aborting a | ||||
|     transaction on every syscalls, regardless whether a transaction has being | ||||
|     initiated before, GLIBS makes the kernel always save/restore HTM state | ||||
|     (it can not even lazily disable it after a certain number of syscall | ||||
|     iterations). | ||||
|      | ||||
|     Because of this shortcoming, Transactional Lock Elision is just enabled | ||||
|     when it has been explicitly set (either by tunables of by a configure | ||||
|     switch) and if kernel aborts HTM transactions on syscalls | ||||
|     (PPC_FEATURE2_HTM_NOSC).  It is reported that using simple benchmark [1], | ||||
|     the context-switch is about 5% faster by not issuing a tabort in every | ||||
|     syscall in newer kernels. | ||||
|      | ||||
|     Checked on powerpc64le-linux-gnu with 4.4.0 kernel (Ubuntu 16.04). | ||||
|      | ||||
|     	* NEWS: Add note about new TLE support on powerpc64le. | ||||
|     	* sysdeps/powerpc/nptl/tcb-offsets.sym (TM_CAPABLE): Remove. | ||||
|     	* sysdeps/powerpc/nptl/tls.h (tcbhead_t): Rename tm_capable to | ||||
|     	__ununsed1. | ||||
|     	(TLS_INIT_TP, TLS_DEFINE_INIT_TP): Remove tm_capable setup. | ||||
|     	(THREAD_GET_TM_CAPABLE, THREAD_SET_TM_CAPABLE): Remove macros. | ||||
|     	* sysdeps/powerpc/powerpc32/sysdep.h, | ||||
|     	sysdeps/powerpc/powerpc64/sysdep.h (ABORT_TRANSACTION_IMPL, | ||||
|     	ABORT_TRANSACTION): Remove macros. | ||||
|     	* sysdeps/powerpc/sysdep.h (ABORT_TRANSACTION): Likewise. | ||||
|     	* sysdeps/unix/sysv/linux/powerpc/elision-conf.c (elision_init): Set | ||||
|     	__pthread_force_elision iff PPC_FEATURE2_HTM_NOSC is set. | ||||
|     	* sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h, | ||||
|     	sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h | ||||
|     	sysdeps/unix/sysv/linux/powerpc/syscall.S (ABORT_TRANSACTION): Remove | ||||
|     	usage. | ||||
|     	* sysdeps/unix/sysv/linux/powerpc/not-errno.h: Remove file. | ||||
|      | ||||
|     Reported-by: Breno Leitão <leitao@debian.org> | ||||
| 
 | ||||
| diff --git a/sysdeps/powerpc/nptl/tcb-offsets.sym b/sysdeps/powerpc/nptl/tcb-offsets.sym
 | ||||
| index e5bb2b3..4c01615 100644
 | ||||
| --- a/sysdeps/powerpc/nptl/tcb-offsets.sym
 | ||||
| +++ b/sysdeps/powerpc/nptl/tcb-offsets.sym
 | ||||
| @@ -21,7 +21,6 @@ DSO_SLOT2			(offsetof (tcbhead_t, dso_slot2) - TLS_TCB_OFFSET - sizeof (tcbhead_
 | ||||
|  #ifdef __powerpc64__ | ||||
|  TCB_AT_PLATFORM			(offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) | ||||
|  #endif | ||||
| -TM_CAPABLE			(offsetof (tcbhead_t, tm_capable) - TLS_TCB_OFFSET - sizeof (tcbhead_t))
 | ||||
|  #ifndef __powerpc64__ | ||||
|  TCB_AT_PLATFORM			(offsetof (tcbhead_t, at_platform) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) | ||||
|  PADDING				(offsetof (tcbhead_t, padding) - TLS_TCB_OFFSET - sizeof(tcbhead_t)) | ||||
| diff --git a/sysdeps/powerpc/nptl/tls.h b/sysdeps/powerpc/nptl/tls.h
 | ||||
| index f88fed5..8317ca7 100644
 | ||||
| --- a/sysdeps/powerpc/nptl/tls.h
 | ||||
| +++ b/sysdeps/powerpc/nptl/tls.h
 | ||||
| @@ -67,8 +67,7 @@ typedef struct
 | ||||
|    uint32_t padding; | ||||
|    uint32_t at_platform; | ||||
|  #endif | ||||
| -  /* Indicate if HTM capable (ISA 2.07).  */
 | ||||
| -  uint32_t tm_capable;
 | ||||
| +  uint32_t __unused;
 | ||||
|    /* Reservation for AT_PLATFORM data - powerpc64.  */ | ||||
|  #ifdef __powerpc64__ | ||||
|    uint32_t at_platform; | ||||
| @@ -142,7 +141,6 @@ register void *__thread_register __asm__ ("r13");
 | ||||
|  # define TLS_INIT_TP(tcbp) \ | ||||
|    ({ 									      \ | ||||
|      __thread_register = (void *) (tcbp) + TLS_TCB_OFFSET;		      \ | ||||
| -    THREAD_SET_TM_CAPABLE (__tcb_hwcap & PPC_FEATURE2_HAS_HTM ? 1 : 0);	      \
 | ||||
|      THREAD_SET_HWCAP (__tcb_hwcap);					      \ | ||||
|      THREAD_SET_AT_PLATFORM (__tcb_platform);				      \ | ||||
|      NULL;								      \ | ||||
| @@ -151,8 +149,6 @@ register void *__thread_register __asm__ ("r13");
 | ||||
|  /* Value passed to 'clone' for initialization of the thread register.  */ | ||||
|  # define TLS_DEFINE_INIT_TP(tp, pd) \ | ||||
|      void *tp = (void *) (pd) + TLS_TCB_OFFSET + TLS_PRE_TCB_SIZE;	      \ | ||||
| -    (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].tm_capable) =	      \
 | ||||
| -      THREAD_GET_TM_CAPABLE ();						      \
 | ||||
|      (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].hwcap) =	      \ | ||||
|        THREAD_GET_HWCAP ();						      \ | ||||
|      (((tcbhead_t *) ((char *) tp - TLS_TCB_OFFSET))[-1].at_platform) =	      \ | ||||
| @@ -210,13 +206,6 @@ register void *__thread_register __asm__ ("r13");
 | ||||
|  		     + TLS_PRE_TCB_SIZE))[-1].pointer_guard		      \ | ||||
|       = THREAD_GET_POINTER_GUARD()) | ||||
|   | ||||
| -/* tm_capable field in TCB head.  */
 | ||||
| -# define THREAD_GET_TM_CAPABLE() \
 | ||||
| -    (((tcbhead_t *) ((char *) __thread_register				      \
 | ||||
| -		     - TLS_TCB_OFFSET))[-1].tm_capable)
 | ||||
| -# define THREAD_SET_TM_CAPABLE(value) \
 | ||||
| -    (THREAD_GET_TM_CAPABLE () = (value))
 | ||||
| -
 | ||||
|  /* hwcap field in TCB head.  */ | ||||
|  # define THREAD_GET_HWCAP() \ | ||||
|      (((tcbhead_t *) ((char *) __thread_register				      \ | ||||
| diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
 | ||||
| index 5f1294e..93097c5 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc32/sysdep.h
 | ||||
| +++ b/sysdeps/powerpc/powerpc32/sysdep.h
 | ||||
| @@ -90,24 +90,7 @@ GOT_LABEL:			;					      \
 | ||||
|    cfi_endproc;								      \ | ||||
|    ASM_SIZE_DIRECTIVE(name) | ||||
|   | ||||
| -#if !IS_IN(rtld) && !defined(__SPE__)
 | ||||
| -# define ABORT_TRANSACTION_IMPL \
 | ||||
| -    cmpwi    2,0;		\
 | ||||
| -    beq      1f;		\
 | ||||
| -    lwz      0,TM_CAPABLE(2);	\
 | ||||
| -    cmpwi    0,0;		\
 | ||||
| -    beq	     1f;		\
 | ||||
| -    li       11,_ABORT_SYSCALL;	\
 | ||||
| -    tabort.  11;		\
 | ||||
| -    .align 4;			\
 | ||||
| -1:
 | ||||
| -#else
 | ||||
| -# define ABORT_TRANSACTION_IMPL
 | ||||
| -#endif
 | ||||
| -#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL
 | ||||
| -
 | ||||
|  #define DO_CALL(syscall)						      \ | ||||
| -    ABORT_TRANSACTION							      \
 | ||||
|      li 0,syscall;							      \ | ||||
|      sc | ||||
|   | ||||
| diff --git a/sysdeps/powerpc/powerpc64/sysdep.h b/sysdeps/powerpc/powerpc64/sysdep.h
 | ||||
| index 2df1d9b..50e64f9 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc64/sysdep.h
 | ||||
| +++ b/sysdeps/powerpc/powerpc64/sysdep.h
 | ||||
| @@ -263,24 +263,7 @@ LT_LABELSUFFIX(name,_name_end): ; \
 | ||||
|    TRACEBACK_MASK(name,mask);	\ | ||||
|    END_2(name) | ||||
|   | ||||
| -#if !IS_IN(rtld)
 | ||||
| -# define ABORT_TRANSACTION_IMPL \
 | ||||
| -    cmpdi    13,0;		\
 | ||||
| -    beq      1f;		\
 | ||||
| -    lwz      0,TM_CAPABLE(13);	\
 | ||||
| -    cmpwi    0,0;		\
 | ||||
| -    beq	     1f;		\
 | ||||
| -    li       11,_ABORT_SYSCALL;	\
 | ||||
| -    tabort.  11;		\
 | ||||
| -    .p2align 4;			\
 | ||||
| -1:
 | ||||
| -#else
 | ||||
| -# define ABORT_TRANSACTION_IMPL
 | ||||
| -#endif
 | ||||
| -#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL
 | ||||
| -
 | ||||
|  #define DO_CALL(syscall) \ | ||||
| -    ABORT_TRANSACTION \
 | ||||
|      li 0,syscall; \ | ||||
|      sc | ||||
|   | ||||
| diff --git a/sysdeps/powerpc/sysdep.h b/sysdeps/powerpc/sysdep.h
 | ||||
| index 8a6d236..c8bf25e 100644
 | ||||
| --- a/sysdeps/powerpc/sysdep.h
 | ||||
| +++ b/sysdeps/powerpc/sysdep.h
 | ||||
| @@ -21,8 +21,6 @@
 | ||||
|   */ | ||||
|  #define _SYSDEPS_SYSDEP_H 1 | ||||
|  #include <bits/hwcap.h> | ||||
| -#include <tls.h>
 | ||||
| -#include <htm.h>
 | ||||
|   | ||||
|  #define PPC_FEATURE_970 (PPC_FEATURE_POWER4 + PPC_FEATURE_HAS_ALTIVEC) | ||||
|   | ||||
| @@ -166,22 +164,4 @@
 | ||||
|  #define ALIGNARG(log2) log2 | ||||
|  #define ASM_SIZE_DIRECTIVE(name) .size name,.-name | ||||
|   | ||||
| -#else
 | ||||
| -
 | ||||
| -/* Linux kernel powerpc documentation [1] states issuing a syscall inside a
 | ||||
| -   transaction is not recommended and may lead to undefined behavior.  It
 | ||||
| -   also states syscalls do not abort transactions.  To avoid such traps,
 | ||||
| -   we abort transaction just before syscalls.
 | ||||
| -
 | ||||
| -   [1] Documentation/powerpc/transactional_memory.txt [Syscalls]  */
 | ||||
| -#if !IS_IN(rtld) && !defined(__SPE__)
 | ||||
| -# define ABORT_TRANSACTION \
 | ||||
| -  ({ 						\
 | ||||
| -    if (THREAD_GET_TM_CAPABLE ())		\
 | ||||
| -      __libc_tabort (_ABORT_SYSCALL);	\
 | ||||
| -  })
 | ||||
| -#else
 | ||||
| -# define ABORT_TRANSACTION
 | ||||
| -#endif
 | ||||
| -
 | ||||
|  #endif	/* __ASSEMBLER__ */ | ||||
| diff --git a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
 | ||||
| index 906882a..fc82bd1 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/powerpc/elision-conf.c
 | ||||
| @@ -127,6 +127,26 @@ elision_init (int argc __attribute__ ((unused)),
 | ||||
|  	       TUNABLE_CALLBACK (set_elision_skip_trylock_internal_abort)); | ||||
|  #endif | ||||
|   | ||||
| +  /* Linux from 3.9 through 4.2 do not abort HTM transaction on syscalls,
 | ||||
| +     instead it suspends the transaction and resumes it when returning to
 | ||||
| +     usercode.  The side-effects of the syscall will always remain visible,
 | ||||
| +     even if the transaction is aborted.  This is an issue when a transaction
 | ||||
| +     is used along with futex syscall, on pthread_cond_wait for instance,
 | ||||
| +     where futex might succeed but the transaction is rolled back leading
 | ||||
| +     the condition variable object in an inconsistent state.
 | ||||
| +
 | ||||
| +     Glibc used to prevent it by always aborting a transaction before issuing
 | ||||
| +     a syscall.  Linux 4.2 also decided to abort active transaction in
 | ||||
| +     syscalls which makes the glibc workaround superflours.  Worse, glibc
 | ||||
| +     transaction abortions leads to a performance issues on recent kernels.
 | ||||
| +
 | ||||
| +     So Lock Elision is just enabled when it has been explict set (either
 | ||||
| +     by tunables of by a configure switch) and if kernel aborts HTM
 | ||||
| +     transactions on syscalls (PPC_FEATURE2_HTM_NOSC)  */
 | ||||
| +
 | ||||
| +  __pthread_force_elision = (__pthread_force_elision
 | ||||
| +			     && GLRO (dl_hwcap2) & PPC_FEATURE2_HTM_NOSC);
 | ||||
| +
 | ||||
|    if (!__pthread_force_elision) | ||||
|      __elision_aconf.try_tbegin = 0; /* Disable elision on rwlocks.  */ | ||||
|  } | ||||
| diff --git a/sysdeps/unix/sysv/linux/powerpc/not-errno.h b/sysdeps/unix/sysv/linux/powerpc/not-errno.h
 | ||||
| deleted file mode 100644 | ||||
| index 27da21b..0000000
 | ||||
| --- a/sysdeps/unix/sysv/linux/powerpc/not-errno.h
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,30 +0,0 @@
 | ||||
| -/* Syscall wrapper that do not set errno.  Linux powerpc version.
 | ||||
| -   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| -   This file is part of the GNU C Library.
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -/* __access_noerrno is used during process initialization in elf/dl-tunables.c
 | ||||
| -   before the TCB is initialized, prohibiting the usage of
 | ||||
| -   ABORT_TRANSACTION.  */
 | ||||
| -#undef ABORT_TRANSACTION
 | ||||
| -#define ABORT_TRANSACTION
 | ||||
| -
 | ||||
| -#include "sysdeps/unix/sysv/linux/not-errno.h"
 | ||||
| -
 | ||||
| -/* Recover ABORT_TRANSACTION's previous value, in order to not affect
 | ||||
| -   other syscalls.  */
 | ||||
| -#undef ABORT_TRANSACTION
 | ||||
| -#define ABORT_TRANSACTION ABORT_TRANSACTION_IMPL
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
 | ||||
| index f7277d5..ec5c525 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
 | ||||
| +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep.h
 | ||||
| @@ -109,7 +109,6 @@
 | ||||
|      register long int r11 __asm__ ("r11");				\ | ||||
|      register long int r12 __asm__ ("r12");				\ | ||||
|      LOADARGS_##nr(name, args);						\ | ||||
| -    ABORT_TRANSACTION;							\
 | ||||
|      __asm__ __volatile__						\ | ||||
|        ("sc   \n\t"							\ | ||||
|         "mfcr %0"							\ | ||||
| diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
 | ||||
| index 0956cf0..1f17f7b 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
 | ||||
| +++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h
 | ||||
| @@ -131,7 +131,6 @@
 | ||||
|      register long int r7  __asm__ ("r7");				\ | ||||
|      register long int r8  __asm__ ("r8");				\ | ||||
|      LOADARGS_##nr (name, ##args);					\ | ||||
| -    ABORT_TRANSACTION;							\
 | ||||
|      __asm__ __volatile__						\ | ||||
|        ("sc\n\t"								\ | ||||
|         "mfcr  %0\n\t"							\ | ||||
| diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S
 | ||||
| index 2da9172..bbab613 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/powerpc/syscall.S
 | ||||
| +++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S
 | ||||
| @@ -18,7 +18,6 @@
 | ||||
|  #include <sysdep.h> | ||||
|   | ||||
|  ENTRY (syscall) | ||||
| -	ABORT_TRANSACTION
 | ||||
|  	mr   r0,r3 | ||||
|  	mr   r3,r4 | ||||
|  	mr   r4,r5 | ||||
							
								
								
									
										35
									
								
								SOURCES/glibc-rh1654010-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								SOURCES/glibc-rh1654010-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | ||||
| commit d527c860f5a3f0ed687bd03f0cb464612dc23408 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Nov 27 16:12:43 2018 +0100 | ||||
| 
 | ||||
|     CVE-2018-19591: if_nametoindex: Fix descriptor for overlong name [BZ #23927] | ||||
| 
 | ||||
| diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
 | ||||
| index e3d08982d9931108..782fc5e1750e9ead 100644
 | ||||
| --- a/sysdeps/unix/sysv/linux/if_index.c
 | ||||
| +++ b/sysdeps/unix/sysv/linux/if_index.c
 | ||||
| @@ -38,11 +38,6 @@ __if_nametoindex (const char *ifname)
 | ||||
|    return 0; | ||||
|  #else | ||||
|    struct ifreq ifr; | ||||
| -  int fd = __opensock ();
 | ||||
| -
 | ||||
| -  if (fd < 0)
 | ||||
| -    return 0;
 | ||||
| -
 | ||||
|    if (strlen (ifname) >= IFNAMSIZ) | ||||
|      { | ||||
|        __set_errno (ENODEV); | ||||
| @@ -50,6 +45,12 @@ __if_nametoindex (const char *ifname)
 | ||||
|      } | ||||
|   | ||||
|    strncpy (ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); | ||||
| +
 | ||||
| +  int fd = __opensock ();
 | ||||
| +
 | ||||
| +  if (fd < 0)
 | ||||
| +    return 0;
 | ||||
| +
 | ||||
|    if (__ioctl (fd, SIOCGIFINDEX, &ifr) < 0) | ||||
|      { | ||||
|        int saved_errno = errno; | ||||
							
								
								
									
										142
									
								
								SOURCES/glibc-rh1654010-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								SOURCES/glibc-rh1654010-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,142 @@ | ||||
| commit c74a91deaa5de416237c02bbb3e41bda76ca4c7b | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Tue Nov 27 21:35:56 2018 +0100 | ||||
| 
 | ||||
|     support: Implement support_quote_string | ||||
|      | ||||
|     Reviewed-by: Jonathan Nieder <jrnieder@gmail.com> | ||||
| 
 | ||||
| diff --git a/support/Makefile b/support/Makefile
 | ||||
| index 2b663fbbfa334ea2..a2536980d1d5a89b 100644
 | ||||
| --- a/support/Makefile
 | ||||
| +++ b/support/Makefile
 | ||||
| @@ -58,6 +58,7 @@ libsupport-routines = \
 | ||||
|    support_openpty \ | ||||
|    support_paths \ | ||||
|    support_quote_blob \ | ||||
| +  support_quote_string \
 | ||||
|    support_record_failure \ | ||||
|    support_run_diff \ | ||||
|    support_shared_allocate \ | ||||
| @@ -196,6 +197,7 @@ tests = \
 | ||||
|    tst-support_capture_subprocess \ | ||||
|    tst-support_format_dns_packet \ | ||||
|    tst-support_quote_blob \ | ||||
| +  tst-support_quote_string \
 | ||||
|    tst-support_record_failure \ | ||||
|    tst-test_compare \ | ||||
|    tst-test_compare_blob \ | ||||
| diff --git a/support/support.h b/support/support.h
 | ||||
| index 9418cd11ef6e684d..835e7173eb566355 100644
 | ||||
| --- a/support/support.h
 | ||||
| +++ b/support/support.h
 | ||||
| @@ -69,6 +69,11 @@ void support_write_file_string (const char *path, const char *contents);
 | ||||
|     the result).  */ | ||||
|  char *support_quote_blob (const void *blob, size_t length); | ||||
|   | ||||
| +/* Quote the contents of the at STR, in such a way that the result
 | ||||
| +   string can be included in a C literal (in single/double quotes,
 | ||||
| +   without putting the quotes into the result).  */
 | ||||
| +char *support_quote_string (const char *str);
 | ||||
| +
 | ||||
|  /* Returns non-zero if the file descriptor is a regular file on a file | ||||
|     system which supports holes (that is, seeking and writing does not | ||||
|     allocate storage for the range of zeros).  FD must refer to a | ||||
| diff --git a/support/support_quote_string.c b/support/support_quote_string.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..d324371b133a4d66
 | ||||
| --- /dev/null
 | ||||
| +++ b/support/support_quote_string.c
 | ||||
| @@ -0,0 +1,26 @@
 | ||||
| +/* Quote a string so that it can be used in C literals.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +
 | ||||
| +char *
 | ||||
| +support_quote_string (const char *str)
 | ||||
| +{
 | ||||
| +  return support_quote_blob (str, strlen (str));
 | ||||
| +}
 | ||||
| diff --git a/support/tst-support_quote_string.c b/support/tst-support_quote_string.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..3c004759b76e21d7
 | ||||
| --- /dev/null
 | ||||
| +++ b/support/tst-support_quote_string.c
 | ||||
| @@ -0,0 +1,60 @@
 | ||||
| +/* Test the support_quote_string function.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  char *p = support_quote_string ("");
 | ||||
| +  TEST_COMPARE (strlen (p), 0);
 | ||||
| +  free (p);
 | ||||
| +  p = support_quote_string ("X");
 | ||||
| +  TEST_COMPARE (strlen (p), 1);
 | ||||
| +  TEST_COMPARE (p[0], 'X');
 | ||||
| +  free (p);
 | ||||
| +
 | ||||
| +  /* Check escaping of backslash-escaped characters, and lack of
 | ||||
| +     escaping for other shell meta-characters.  */
 | ||||
| +  p = support_quote_string ("$()*?`@[]{}~\'\"X");
 | ||||
| +  TEST_COMPARE (strcmp (p, "$()*?`@[]{}~\\'\\\"X"), 0);
 | ||||
| +  free (p);
 | ||||
| +
 | ||||
| +  /* Check lack of escaping for letters and digits.  */
 | ||||
| +#define LETTERS_AND_DIGTS                       \
 | ||||
| +  "abcdefghijklmnopqrstuvwxyz"                  \
 | ||||
| +  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                  \
 | ||||
| +  "0123456789"
 | ||||
| +  p = support_quote_string (LETTERS_AND_DIGTS "@");
 | ||||
| +  TEST_COMPARE (strcmp (p, LETTERS_AND_DIGTS "@"), 0);
 | ||||
| +  free (p);
 | ||||
| +
 | ||||
| +  /* Check escaping of control characters and other non-printable
 | ||||
| +     characters.  */
 | ||||
| +  p = support_quote_string ("\r\n\t\a\b\f\v\1\177\200\377@");
 | ||||
| +  TEST_COMPARE (strcmp (p, "\\r\\n\\t\\a\\b\\f\\v\\001"
 | ||||
| +                        "\\177\\200\\377@"), 0);
 | ||||
| +  free (p);
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										26
									
								
								SOURCES/glibc-rh1654010-3.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								SOURCES/glibc-rh1654010-3.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | ||||
| commit 47d8d9a2172f827a8dde7695f415aa6f78a82d0e | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Wed Nov 28 07:00:48 2018 +0100 | ||||
| 
 | ||||
|     support_quote_string: Do not use str parameter name | ||||
|      | ||||
|     This avoids a build failure if this identifier is used as a macro | ||||
|     in a test. | ||||
| 
 | ||||
| diff --git a/support/support.h b/support/support.h
 | ||||
| index 835e7173eb566355..c3ad76901e352ee7 100644
 | ||||
| --- a/support/support.h
 | ||||
| +++ b/support/support.h
 | ||||
| @@ -69,10 +69,10 @@ void support_write_file_string (const char *path, const char *contents);
 | ||||
|     the result).  */ | ||||
|  char *support_quote_blob (const void *blob, size_t length); | ||||
|   | ||||
| -/* Quote the contents of the at STR, in such a way that the result
 | ||||
| +/* Quote the contents of the string, in such a way that the result
 | ||||
|     string can be included in a C literal (in single/double quotes, | ||||
|     without putting the quotes into the result).  */ | ||||
| -char *support_quote_string (const char *str);
 | ||||
| +char *support_quote_string (const char *);
 | ||||
|   | ||||
|  /* Returns non-zero if the file descriptor is a regular file on a file | ||||
|     system which supports holes (that is, seeking and writing does not | ||||
							
								
								
									
										32
									
								
								SOURCES/glibc-rh1654010-4.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								SOURCES/glibc-rh1654010-4.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| commit 02cd5c1a8d033d7f91fea12a66bb44d1bbf85f76 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Sat Dec 1 21:43:36 2018 +0100 | ||||
| 
 | ||||
|     support: Close original descriptors in support_capture_subprocess | ||||
| 
 | ||||
| diff --git a/support/support_capture_subprocess.c b/support/support_capture_subprocess.c
 | ||||
| index 6d2029e13bd6ae73..93f6ea310290000a 100644
 | ||||
| --- a/support/support_capture_subprocess.c
 | ||||
| +++ b/support/support_capture_subprocess.c
 | ||||
| @@ -59,8 +59,12 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
 | ||||
|   | ||||
|    int stdout_pipe[2]; | ||||
|    xpipe (stdout_pipe); | ||||
| +  TEST_VERIFY (stdout_pipe[0] > STDERR_FILENO);
 | ||||
| +  TEST_VERIFY (stdout_pipe[1] > STDERR_FILENO);
 | ||||
|    int stderr_pipe[2]; | ||||
|    xpipe (stderr_pipe); | ||||
| +  TEST_VERIFY (stderr_pipe[0] > STDERR_FILENO);
 | ||||
| +  TEST_VERIFY (stderr_pipe[1] > STDERR_FILENO);
 | ||||
|   | ||||
|    TEST_VERIFY (fflush (stdout) == 0); | ||||
|    TEST_VERIFY (fflush (stderr) == 0); | ||||
| @@ -72,6 +76,8 @@ support_capture_subprocess (void (*callback) (void *), void *closure)
 | ||||
|        xclose (stderr_pipe[0]); | ||||
|        xdup2 (stdout_pipe[1], STDOUT_FILENO); | ||||
|        xdup2 (stderr_pipe[1], STDERR_FILENO); | ||||
| +      xclose (stdout_pipe[1]);
 | ||||
| +      xclose (stderr_pipe[1]);
 | ||||
|        callback (closure); | ||||
|        _exit (0); | ||||
|      } | ||||
							
								
								
									
										594
									
								
								SOURCES/glibc-rh1654010-5.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										594
									
								
								SOURCES/glibc-rh1654010-5.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,594 @@ | ||||
| commit f255336a9301619519045548acb2e1027065a837 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Thu Dec 6 15:39:42 2018 +0100 | ||||
| 
 | ||||
|     support: Implement <support/descriptors.h> to track file descriptors | ||||
| 
 | ||||
| diff --git a/support/Makefile b/support/Makefile
 | ||||
| index a2536980d1d5a89b..93a514301654132e 100644
 | ||||
| --- a/support/Makefile
 | ||||
| +++ b/support/Makefile
 | ||||
| @@ -46,6 +46,7 @@ libsupport-routines = \
 | ||||
|    support_chroot \ | ||||
|    support_copy_file_range \ | ||||
|    support_descriptor_supports_holes \ | ||||
| +  support_descriptors \
 | ||||
|    support_enter_mount_namespace \ | ||||
|    support_enter_network_namespace \ | ||||
|    support_format_address_family \ | ||||
| @@ -195,6 +196,7 @@ tests = \
 | ||||
|    tst-support-namespace \ | ||||
|    tst-support_blob_repeat \ | ||||
|    tst-support_capture_subprocess \ | ||||
| +  tst-support_descriptors \
 | ||||
|    tst-support_format_dns_packet \ | ||||
|    tst-support_quote_blob \ | ||||
|    tst-support_quote_string \ | ||||
| diff --git a/support/check.h b/support/check.h
 | ||||
| index e6765289f2492501..7ea9a86a9c7ed055 100644
 | ||||
| --- a/support/check.h
 | ||||
| +++ b/support/check.h
 | ||||
| @@ -183,6 +183,10 @@ int support_report_failure (int status)
 | ||||
|  /* Internal function used to test the failure recording framework.  */ | ||||
|  void support_record_failure_reset (void); | ||||
|   | ||||
| +/* Returns true or false depending on whether there have been test
 | ||||
| +   failures or not.  */
 | ||||
| +int support_record_failure_is_failed (void);
 | ||||
| +
 | ||||
|  __END_DECLS | ||||
|   | ||||
|  #endif /* SUPPORT_CHECK_H */ | ||||
| diff --git a/support/descriptors.h b/support/descriptors.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..8ec4cbbdfb8f1770
 | ||||
| --- /dev/null
 | ||||
| +++ b/support/descriptors.h
 | ||||
| @@ -0,0 +1,47 @@
 | ||||
| +/* Monitoring file descriptor usage.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#ifndef SUPPORT_DESCRIPTORS_H
 | ||||
| +#define SUPPORT_DESCRIPTORS_H
 | ||||
| +
 | ||||
| +#include <stdio.h>
 | ||||
| +
 | ||||
| +/* Opaque pointer, for capturing file descriptor lists.  */
 | ||||
| +struct support_descriptors;
 | ||||
| +
 | ||||
| +/* Record the currently open file descriptors and store them in the
 | ||||
| +   returned list.  Terminate the process if the listing operation
 | ||||
| +   fails.  */
 | ||||
| +struct support_descriptors *support_descriptors_list (void);
 | ||||
| +
 | ||||
| +/* Deallocate the list of descriptors.  */
 | ||||
| +void support_descriptors_free (struct support_descriptors *);
 | ||||
| +
 | ||||
| +/* Write the list of descriptors to STREAM, adding PREFIX to each
 | ||||
| +   line.  */
 | ||||
| +void support_descriptors_dump (struct support_descriptors *,
 | ||||
| +                               const char *prefix, FILE *stream);
 | ||||
| +
 | ||||
| +/* Check for file descriptor leaks and other file descriptor changes:
 | ||||
| +   Compare the current list of descriptors with the passed list.
 | ||||
| +   Record a test failure if there are additional open descriptors,
 | ||||
| +   descriptors have been closed, or if a change in file descriptor can
 | ||||
| +   be detected.  */
 | ||||
| +void support_descriptors_check (struct support_descriptors *);
 | ||||
| +
 | ||||
| +#endif /* SUPPORT_DESCRIPTORS_H */
 | ||||
| diff --git a/support/support_descriptors.c b/support/support_descriptors.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..d66cf550800201c5
 | ||||
| --- /dev/null
 | ||||
| +++ b/support/support_descriptors.c
 | ||||
| @@ -0,0 +1,274 @@
 | ||||
| +/* Monitoring file descriptor usage.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <dirent.h>
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <sys/stat.h>
 | ||||
| +#include <sys/sysmacros.h>
 | ||||
| +#include <xunistd.h>
 | ||||
| +
 | ||||
| +struct procfs_descriptor
 | ||||
| +{
 | ||||
| +  int fd;
 | ||||
| +  char *link_target;
 | ||||
| +  dev_t dev;
 | ||||
| +  ino64_t ino;
 | ||||
| +};
 | ||||
| +
 | ||||
| +/* Used with qsort.  */
 | ||||
| +static int
 | ||||
| +descriptor_compare (const void *l, const void *r)
 | ||||
| +{
 | ||||
| +  const struct procfs_descriptor *left = l;
 | ||||
| +  const struct procfs_descriptor *right = r;
 | ||||
| +  /* Cannot overflow due to limited file descriptor range.  */
 | ||||
| +  return left->fd - right->fd;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define DYNARRAY_STRUCT descriptor_list
 | ||||
| +#define DYNARRAY_ELEMENT struct procfs_descriptor
 | ||||
| +#define DYNARRAY_PREFIX descriptor_list_
 | ||||
| +#define DYNARRAY_ELEMENT_FREE(e) free ((e)->link_target)
 | ||||
| +#define DYNARRAY_INITIAL_SIZE 0
 | ||||
| +#include <malloc/dynarray-skeleton.c>
 | ||||
| +
 | ||||
| +struct support_descriptors
 | ||||
| +{
 | ||||
| +  struct descriptor_list list;
 | ||||
| +};
 | ||||
| +
 | ||||
| +struct support_descriptors *
 | ||||
| +support_descriptors_list (void)
 | ||||
| +{
 | ||||
| +  struct support_descriptors *result = xmalloc (sizeof (*result));
 | ||||
| +  descriptor_list_init (&result->list);
 | ||||
| +
 | ||||
| +  DIR *fds = opendir ("/proc/self/fd");
 | ||||
| +  if (fds == NULL)
 | ||||
| +    FAIL_EXIT1 ("opendir (\"/proc/self/fd\"): %m");
 | ||||
| +
 | ||||
| +  while (true)
 | ||||
| +    {
 | ||||
| +      errno = 0;
 | ||||
| +      struct dirent64 *e = readdir64 (fds);
 | ||||
| +      if (e == NULL)
 | ||||
| +        {
 | ||||
| +          if (errno != 0)
 | ||||
| +            FAIL_EXIT1 ("readdir: %m");
 | ||||
| +          break;
 | ||||
| +        }
 | ||||
| +
 | ||||
| +      if (e->d_name[0] == '.')
 | ||||
| +        continue;
 | ||||
| +
 | ||||
| +      char *endptr;
 | ||||
| +      long int fd = strtol (e->d_name, &endptr, 10);
 | ||||
| +      if (*endptr != '\0' || fd < 0 || fd > INT_MAX)
 | ||||
| +        FAIL_EXIT1 ("readdir: invalid file descriptor name: /proc/self/fd/%s",
 | ||||
| +                    e->d_name);
 | ||||
| +
 | ||||
| +      /* Skip the descriptor which is used to enumerate the
 | ||||
| +         descriptors.  */
 | ||||
| +      if (fd == dirfd (fds))
 | ||||
| +        continue;
 | ||||
| +
 | ||||
| +      char *target;
 | ||||
| +      {
 | ||||
| +        char *path = xasprintf ("/proc/self/fd/%ld", fd);
 | ||||
| +        target = xreadlink (path);
 | ||||
| +        free (path);
 | ||||
| +      }
 | ||||
| +      struct stat64 st;
 | ||||
| +      if (fstat64 (fd, &st) != 0)
 | ||||
| +        FAIL_EXIT1 ("readdir: fstat64 (%ld) failed: %m", fd);
 | ||||
| +
 | ||||
| +      struct procfs_descriptor *item = descriptor_list_emplace (&result->list);
 | ||||
| +      if (item == NULL)
 | ||||
| +        FAIL_EXIT1 ("descriptor_list_emplace: %m");
 | ||||
| +      item->fd = fd;
 | ||||
| +      item->link_target = target;
 | ||||
| +      item->dev = st.st_dev;
 | ||||
| +      item->ino = st.st_ino;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  closedir (fds);
 | ||||
| +
 | ||||
| +  /* Perform a merge join between descrs and current.  This assumes
 | ||||
| +     that the arrays are sorted by file descriptor.  */
 | ||||
| +
 | ||||
| +  qsort (descriptor_list_begin (&result->list),
 | ||||
| +         descriptor_list_size (&result->list),
 | ||||
| +         sizeof (struct procfs_descriptor), descriptor_compare);
 | ||||
| +
 | ||||
| +  return result;
 | ||||
| +}
 | ||||
| +
 | ||||
| +void
 | ||||
| +support_descriptors_free (struct support_descriptors *descrs)
 | ||||
| +{
 | ||||
| +  descriptor_list_free (&descrs->list);
 | ||||
| +  free (descrs);
 | ||||
| +}
 | ||||
| +
 | ||||
| +void
 | ||||
| +support_descriptors_dump (struct support_descriptors *descrs,
 | ||||
| +                          const char *prefix, FILE *fp)
 | ||||
| +{
 | ||||
| +  struct procfs_descriptor *end = descriptor_list_end (&descrs->list);
 | ||||
| +  for (struct procfs_descriptor *d = descriptor_list_begin (&descrs->list);
 | ||||
| +       d != end; ++d)
 | ||||
| +    {
 | ||||
| +      char *quoted = support_quote_string (d->link_target);
 | ||||
| +      fprintf (fp, "%s%d: target=\"%s\" major=%lld minor=%lld ino=%lld\n",
 | ||||
| +               prefix, d->fd, quoted,
 | ||||
| +               (long long int) major (d->dev),
 | ||||
| +               (long long int) minor (d->dev),
 | ||||
| +               (long long int) d->ino);
 | ||||
| +      free (quoted);
 | ||||
| +    }
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +dump_mismatch (bool *first,
 | ||||
| +               struct support_descriptors *descrs,
 | ||||
| +               struct support_descriptors *current)
 | ||||
| +{
 | ||||
| +  if (*first)
 | ||||
| +    *first = false;
 | ||||
| +  else
 | ||||
| +    return;
 | ||||
| +
 | ||||
| +  puts ("error: Differences found in descriptor set");
 | ||||
| +  puts ("Reference descriptor set:");
 | ||||
| +  support_descriptors_dump (descrs, "  ", stdout);
 | ||||
| +  puts ("Current descriptor set:");
 | ||||
| +  support_descriptors_dump (current, "  ", stdout);
 | ||||
| +  puts ("Differences:");
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +report_closed_descriptor (bool *first,
 | ||||
| +                          struct support_descriptors *descrs,
 | ||||
| +                          struct support_descriptors *current,
 | ||||
| +                          struct procfs_descriptor *left)
 | ||||
| +{
 | ||||
| +  support_record_failure ();
 | ||||
| +  dump_mismatch (first, descrs, current);
 | ||||
| +  printf ("error: descriptor %d was closed\n", left->fd);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +report_opened_descriptor (bool *first,
 | ||||
| +                          struct support_descriptors *descrs,
 | ||||
| +                          struct support_descriptors *current,
 | ||||
| +                          struct procfs_descriptor *right)
 | ||||
| +{
 | ||||
| +  support_record_failure ();
 | ||||
| +  dump_mismatch (first, descrs, current);
 | ||||
| +  char *quoted = support_quote_string (right->link_target);
 | ||||
| +  printf ("error: descriptor %d was opened (\"%s\")\n", right->fd, quoted);
 | ||||
| +  free (quoted);
 | ||||
| +}
 | ||||
| +
 | ||||
| +void
 | ||||
| +support_descriptors_check (struct support_descriptors *descrs)
 | ||||
| +{
 | ||||
| +  struct support_descriptors *current = support_descriptors_list ();
 | ||||
| +
 | ||||
| +  /* Perform a merge join between descrs and current.  This assumes
 | ||||
| +     that the arrays are sorted by file descriptor.  */
 | ||||
| +
 | ||||
| +  struct procfs_descriptor *left = descriptor_list_begin (&descrs->list);
 | ||||
| +  struct procfs_descriptor *left_end = descriptor_list_end (&descrs->list);
 | ||||
| +  struct procfs_descriptor *right = descriptor_list_begin (¤t->list);
 | ||||
| +  struct procfs_descriptor *right_end = descriptor_list_end (¤t->list);
 | ||||
| +
 | ||||
| +  bool first = true;
 | ||||
| +  while (left != left_end && right != right_end)
 | ||||
| +    {
 | ||||
| +      if (left->fd == right->fd)
 | ||||
| +        {
 | ||||
| +          if (strcmp (left->link_target, right->link_target) != 0)
 | ||||
| +            {
 | ||||
| +              support_record_failure ();
 | ||||
| +              char *left_quoted = support_quote_string (left->link_target);
 | ||||
| +              char *right_quoted = support_quote_string (right->link_target);
 | ||||
| +              dump_mismatch (&first, descrs, current);
 | ||||
| +              printf ("error: descriptor %d changed from \"%s\" to \"%s\"\n",
 | ||||
| +                      left->fd, left_quoted, right_quoted);
 | ||||
| +              free (left_quoted);
 | ||||
| +              free (right_quoted);
 | ||||
| +            }
 | ||||
| +          if (left->dev != right->dev)
 | ||||
| +            {
 | ||||
| +              support_record_failure ();
 | ||||
| +              dump_mismatch (&first, descrs, current);
 | ||||
| +              printf ("error: descriptor %d changed device"
 | ||||
| +                      " from %lld:%lld to %lld:%lld\n",
 | ||||
| +                      left->fd,
 | ||||
| +                      (long long int) major (left->dev),
 | ||||
| +                      (long long int) minor (left->dev),
 | ||||
| +                      (long long int) major (right->dev),
 | ||||
| +                      (long long int) minor (right->dev));
 | ||||
| +            }
 | ||||
| +          if (left->ino != right->ino)
 | ||||
| +            {
 | ||||
| +              support_record_failure ();
 | ||||
| +              dump_mismatch (&first, descrs, current);
 | ||||
| +              printf ("error: descriptor %d changed ino from %lld to %lld\n",
 | ||||
| +                      left->fd,
 | ||||
| +                      (long long int) left->ino, (long long int) right->ino);
 | ||||
| +            }
 | ||||
| +          ++left;
 | ||||
| +          ++right;
 | ||||
| +        }
 | ||||
| +      else if (left->fd < right->fd)
 | ||||
| +        {
 | ||||
| +          /* Gap on the right.  */
 | ||||
| +          report_closed_descriptor (&first, descrs, current, left);
 | ||||
| +          ++left;
 | ||||
| +        }
 | ||||
| +      else
 | ||||
| +        {
 | ||||
| +          /* Gap on the left.  */
 | ||||
| +          TEST_VERIFY_EXIT (left->fd > right->fd);
 | ||||
| +          report_opened_descriptor (&first, descrs, current, right);
 | ||||
| +          ++right;
 | ||||
| +        }
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  while (left != left_end)
 | ||||
| +    {
 | ||||
| +      /* Closed descriptors (more descriptors on the left).  */
 | ||||
| +      report_closed_descriptor (&first, descrs, current, left);
 | ||||
| +      ++left;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  while (right != right_end)
 | ||||
| +    {
 | ||||
| +      /* Opened descriptors (more descriptors on the right).  */
 | ||||
| +      report_opened_descriptor (&first, descrs, current, right);
 | ||||
| +      ++right;
 | ||||
| +    }
 | ||||
| +
 | ||||
| +  support_descriptors_free (current);
 | ||||
| +}
 | ||||
| diff --git a/support/support_record_failure.c b/support/support_record_failure.c
 | ||||
| index 356798f55608ca71..17ab1d80ef2bbdea 100644
 | ||||
| --- a/support/support_record_failure.c
 | ||||
| +++ b/support/support_record_failure.c
 | ||||
| @@ -104,3 +104,11 @@ support_record_failure_reset (void)
 | ||||
|    __atomic_store_n (&state->failed, 0, __ATOMIC_RELAXED); | ||||
|    __atomic_add_fetch (&state->counter, 0, __ATOMIC_RELAXED); | ||||
|  } | ||||
| +
 | ||||
| +int
 | ||||
| +support_record_failure_is_failed (void)
 | ||||
| +{
 | ||||
| +  /* Relaxed MO is sufficient because we need (blocking) external
 | ||||
| +     synchronization for reliable test error reporting anyway.  */
 | ||||
| +  return __atomic_load_n (&state->failed, __ATOMIC_RELAXED);
 | ||||
| +}
 | ||||
| diff --git a/support/tst-support_descriptors.c b/support/tst-support_descriptors.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..5e9e824bc3820499
 | ||||
| --- /dev/null
 | ||||
| +++ b/support/tst-support_descriptors.c
 | ||||
| @@ -0,0 +1,198 @@
 | ||||
| +/* Tests for monitoring file descriptor usage.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <fcntl.h>
 | ||||
| +#include <stdbool.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/capture_subprocess.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/descriptors.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +#include <support/xunistd.h>
 | ||||
| +
 | ||||
| +/* This is the next free descriptor that the subprocess will pick.  */
 | ||||
| +static int free_descriptor;
 | ||||
| +
 | ||||
| +static void
 | ||||
| +subprocess_no_change (void *closure)
 | ||||
| +{
 | ||||
| +  struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +  int fd = xopen ("/dev/null", O_WRONLY, 0);
 | ||||
| +  TEST_COMPARE (fd, free_descriptor);
 | ||||
| +  xclose (fd);
 | ||||
| +  support_descriptors_free (descrs);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +subprocess_closed_descriptor (void *closure)
 | ||||
| +{
 | ||||
| +  int fd = xopen ("/dev/null", O_WRONLY, 0);
 | ||||
| +  TEST_COMPARE (fd, free_descriptor);
 | ||||
| +  struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +  xclose (fd);
 | ||||
| +  support_descriptors_check (descrs); /* Will report failure.  */
 | ||||
| +  puts ("EOT");
 | ||||
| +  support_descriptors_free (descrs);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +subprocess_opened_descriptor (void *closure)
 | ||||
| +{
 | ||||
| +  struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +  int fd = xopen ("/dev/null", O_WRONLY, 0);
 | ||||
| +  TEST_COMPARE (fd, free_descriptor);
 | ||||
| +  support_descriptors_check (descrs); /* Will report failure.  */
 | ||||
| +  puts ("EOT");
 | ||||
| +  support_descriptors_free (descrs);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +subprocess_changed_descriptor (void *closure)
 | ||||
| +{
 | ||||
| +  int fd = xopen ("/dev/null", O_WRONLY, 0);
 | ||||
| +  TEST_COMPARE (fd, free_descriptor);
 | ||||
| +  struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +  xclose (fd);
 | ||||
| +  TEST_COMPARE (xopen ("/dev", O_DIRECTORY | O_RDONLY, 0), fd);
 | ||||
| +  support_descriptors_check (descrs); /* Will report failure.  */
 | ||||
| +  puts ("EOT");
 | ||||
| +  support_descriptors_free (descrs);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static void
 | ||||
| +report_subprocess_output (const char *name,
 | ||||
| +                          struct support_capture_subprocess *proc)
 | ||||
| +{
 | ||||
| +  printf ("info: BEGIN %s output\n"
 | ||||
| +          "%s"
 | ||||
| +          "info: END %s output\n",
 | ||||
| +          name, proc->out.buffer, name);
 | ||||
| +}
 | ||||
| +
 | ||||
| +/* Use an explicit flag to preserve failure status across
 | ||||
| +   support_record_failure_reset calls.  */
 | ||||
| +static bool good = true;
 | ||||
| +
 | ||||
| +static void
 | ||||
| +test_run (void)
 | ||||
| +{
 | ||||
| +  struct support_capture_subprocess proc = support_capture_subprocess
 | ||||
| +    (&subprocess_no_change, NULL);
 | ||||
| +  support_capture_subprocess_check (&proc, "subprocess_no_change",
 | ||||
| +                                    0, sc_allow_none);
 | ||||
| +  support_capture_subprocess_free (&proc);
 | ||||
| +
 | ||||
| +  char *expected = xasprintf ("\nDifferences:\n"
 | ||||
| +                              "error: descriptor %d was closed\n"
 | ||||
| +                              "EOT\n",
 | ||||
| +                              free_descriptor);
 | ||||
| +  good = good && !support_record_failure_is_failed ();
 | ||||
| +  proc = support_capture_subprocess (&subprocess_closed_descriptor, NULL);
 | ||||
| +  good = good && support_record_failure_is_failed ();
 | ||||
| +  support_record_failure_reset (); /* Discard the reported error.  */
 | ||||
| +  report_subprocess_output ("subprocess_closed_descriptor", &proc);
 | ||||
| +  TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
 | ||||
| +  support_capture_subprocess_check (&proc, "subprocess_closed_descriptor",
 | ||||
| +                                    0, sc_allow_stdout);
 | ||||
| +  support_capture_subprocess_free (&proc);
 | ||||
| +  free (expected);
 | ||||
| +
 | ||||
| +  expected = xasprintf ("\nDifferences:\n"
 | ||||
| +                        "error: descriptor %d was opened (\"/dev/null\")\n"
 | ||||
| +                        "EOT\n",
 | ||||
| +                        free_descriptor);
 | ||||
| +  good = good && !support_record_failure_is_failed ();
 | ||||
| +  proc = support_capture_subprocess (&subprocess_opened_descriptor, NULL);
 | ||||
| +  good = good && support_record_failure_is_failed ();
 | ||||
| +  support_record_failure_reset (); /* Discard the reported error.  */
 | ||||
| +  report_subprocess_output ("subprocess_opened_descriptor", &proc);
 | ||||
| +  TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
 | ||||
| +  support_capture_subprocess_check (&proc, "subprocess_opened_descriptor",
 | ||||
| +                                    0, sc_allow_stdout);
 | ||||
| +  support_capture_subprocess_free (&proc);
 | ||||
| +  free (expected);
 | ||||
| +
 | ||||
| +  expected = xasprintf ("\nDifferences:\n"
 | ||||
| +                        "error: descriptor %d changed from \"/dev/null\""
 | ||||
| +                        " to \"/dev\"\n"
 | ||||
| +                        "error: descriptor %d changed ino ",
 | ||||
| +                        free_descriptor, free_descriptor);
 | ||||
| +  good = good && !support_record_failure_is_failed ();
 | ||||
| +  proc = support_capture_subprocess (&subprocess_changed_descriptor, NULL);
 | ||||
| +  good = good && support_record_failure_is_failed ();
 | ||||
| +  support_record_failure_reset (); /* Discard the reported error.  */
 | ||||
| +  report_subprocess_output ("subprocess_changed_descriptor", &proc);
 | ||||
| +  TEST_VERIFY (strstr (proc.out.buffer, expected) != NULL);
 | ||||
| +  support_capture_subprocess_check (&proc, "subprocess_changed_descriptor",
 | ||||
| +                                    0, sc_allow_stdout);
 | ||||
| +  support_capture_subprocess_free (&proc);
 | ||||
| +  free (expected);
 | ||||
| +}
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  puts ("info: initial descriptor set");
 | ||||
| +  {
 | ||||
| +    struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +    support_descriptors_dump (descrs, "info:  ", stdout);
 | ||||
| +    support_descriptors_free (descrs);
 | ||||
| +  }
 | ||||
| +
 | ||||
| +  free_descriptor = xopen ("/dev/null", O_WRONLY, 0);
 | ||||
| +  puts ("info: descriptor set with additional free descriptor");
 | ||||
| +  {
 | ||||
| +    struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +    support_descriptors_dump (descrs, "info:  ", stdout);
 | ||||
| +    support_descriptors_free (descrs);
 | ||||
| +  }
 | ||||
| +  TEST_VERIFY (free_descriptor >= 3);
 | ||||
| +  xclose (free_descriptor);
 | ||||
| +
 | ||||
| +  /* Initial test run without a sentinel descriptor.  The presence of
 | ||||
| +     such a descriptor exercises different conditions in the list
 | ||||
| +     comparison in support_descriptors_check.  */
 | ||||
| +  test_run ();
 | ||||
| +
 | ||||
| +  /* Allocate a sentinel descriptor at the end of the descriptor list,
 | ||||
| +     after free_descriptor.  */
 | ||||
| +  int sentinel_fd;
 | ||||
| +  {
 | ||||
| +    int fd = xopen ("/dev/full", O_WRONLY, 0);
 | ||||
| +    TEST_COMPARE (fd, free_descriptor);
 | ||||
| +    sentinel_fd = dup (fd);
 | ||||
| +    TEST_VERIFY_EXIT (sentinel_fd > fd);
 | ||||
| +    xclose (fd);
 | ||||
| +  }
 | ||||
| +  puts ("info: descriptor set with sentinel descriptor");
 | ||||
| +  {
 | ||||
| +    struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +    support_descriptors_dump (descrs, "info:  ", stdout);
 | ||||
| +    support_descriptors_free (descrs);
 | ||||
| +  }
 | ||||
| +
 | ||||
| +  /* Second test run with sentinel descriptor.  */
 | ||||
| +  test_run ();
 | ||||
| +
 | ||||
| +  xclose (sentinel_fd);
 | ||||
| +
 | ||||
| +  return !good;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										86
									
								
								SOURCES/glibc-rh1654010-6.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								SOURCES/glibc-rh1654010-6.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,86 @@ | ||||
| commit 899478c2bfa00c5df8d8bedb52effbb065700278 | ||||
| Author: Florian Weimer <fweimer@redhat.com> | ||||
| Date:   Thu Dec 6 15:39:50 2018 +0100 | ||||
| 
 | ||||
|     inet/tst-if_index-long: New test case for CVE-2018-19591 [BZ #23927] | ||||
| 
 | ||||
| diff --git a/inet/Makefile b/inet/Makefile
 | ||||
| index 09f5ba78fc5f3120..7782913b4c06f057 100644
 | ||||
| --- a/inet/Makefile
 | ||||
| +++ b/inet/Makefile
 | ||||
| @@ -52,7 +52,7 @@ aux := check_pf check_native ifreq
 | ||||
|  tests := htontest test_ifindex tst-ntoa tst-ether_aton tst-network \ | ||||
|  	 tst-gethnm test-ifaddrs bug-if1 test-inet6_opt tst-ether_line \ | ||||
|  	 tst-getni1 tst-getni2 tst-inet6_rth tst-checks tst-checks-posix \ | ||||
| -	 tst-sockaddr test-hnto-types
 | ||||
| +	 tst-sockaddr test-hnto-types tst-if_index-long
 | ||||
|   | ||||
|  # tst-deadline must be linked statically so that we can access | ||||
|  # internal functions. | ||||
| diff --git a/inet/tst-if_index-long.c b/inet/tst-if_index-long.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..3dc74874e5310945
 | ||||
| --- /dev/null
 | ||||
| +++ b/inet/tst-if_index-long.c
 | ||||
| @@ -0,0 +1,61 @@
 | ||||
| +/* Check for descriptor leak in if_nametoindex with a long interface name.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* This test checks for a descriptor leak in case of a long interface
 | ||||
| +   name (CVE-2018-19591, bug 23927).  */
 | ||||
| +
 | ||||
| +#include <errno.h>
 | ||||
| +#include <net/if.h>
 | ||||
| +#include <netdb.h>
 | ||||
| +#include <string.h>
 | ||||
| +#include <support/check.h>
 | ||||
| +#include <support/descriptors.h>
 | ||||
| +#include <support/support.h>
 | ||||
| +
 | ||||
| +static int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  struct support_descriptors *descrs = support_descriptors_list ();
 | ||||
| +
 | ||||
| +  /* Prepare a name which is just as long as required for trigging the
 | ||||
| +     bug.  */
 | ||||
| +  char name[IFNAMSIZ + 1];
 | ||||
| +  memset (name, 'A', IFNAMSIZ);
 | ||||
| +  name[IFNAMSIZ] = '\0';
 | ||||
| +  TEST_COMPARE (strlen (name), IFNAMSIZ);
 | ||||
| +  struct ifreq ifr;
 | ||||
| +  TEST_COMPARE (strlen (name), sizeof (ifr.ifr_name));
 | ||||
| +
 | ||||
| +  /* Test directly via if_nametoindex.  */
 | ||||
| +  TEST_COMPARE (if_nametoindex (name), 0);
 | ||||
| +  TEST_COMPARE (errno, ENODEV);
 | ||||
| +  support_descriptors_check (descrs);
 | ||||
| +
 | ||||
| +  /* Same test via getaddrinfo.  */
 | ||||
| +  char *host = xasprintf ("fea0::%%%s", name);
 | ||||
| +  struct addrinfo hints = { .ai_flags = AI_NUMERICHOST, };
 | ||||
| +  struct addrinfo *ai;
 | ||||
| +  TEST_COMPARE (getaddrinfo (host, NULL, &hints, &ai), EAI_NONAME);
 | ||||
| +  support_descriptors_check (descrs);
 | ||||
| +
 | ||||
| +  support_descriptors_free (descrs);
 | ||||
| +
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										446
									
								
								SOURCES/glibc-rh1654872-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										446
									
								
								SOURCES/glibc-rh1654872-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,446 @@ | ||||
| commit 3d265911c2aac65d978f679101594f9071024874 | ||||
| Author: Andreas Schwab <schwab@suse.de> | ||||
| Date:   Mon Nov 12 11:11:40 2018 +0100 | ||||
| 
 | ||||
|     Reindent nptl/pthread_rwlock_common.c | ||||
| 
 | ||||
| diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
 | ||||
| index a290d08332b802a5..5dd534271aed6b41 100644
 | ||||
| --- a/nptl/pthread_rwlock_common.c
 | ||||
| +++ b/nptl/pthread_rwlock_common.c
 | ||||
| @@ -34,7 +34,7 @@
 | ||||
|   | ||||
|     A thread is allowed to acquire a read lock recursively (i.e., have rdlock | ||||
|     critical sections that overlap in sequenced-before) unless the kind of the | ||||
| -   rwlock is set to PTHREAD_RWLOCK_PREFER_WRITERS_NONRECURSIVE_NP.
 | ||||
| +   rwlock is set to PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP.
 | ||||
|   | ||||
|     This lock is built so that workloads of mostly readers can be executed with | ||||
|     low runtime overheads.  This matches that the default kind of the lock is | ||||
| @@ -46,7 +46,7 @@
 | ||||
|     An uncontended write lock acquisition is as fast as for a normal | ||||
|     exclusive mutex but writer contention is somewhat more costly due to | ||||
|     keeping track of the exact number of writers.  If the rwlock kind requests | ||||
| -   writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITERS_NP or the
 | ||||
| +   writers to be preferred (i.e., PTHREAD_RWLOCK_PREFER_WRITER_NP or the
 | ||||
|     no-recursive-readers variant of it), then writer--to--writer lock ownership | ||||
|     hand-over is fairly fast and bypasses lock acquisition attempts by readers. | ||||
|     The costs of lock ownership transfer between readers and writers vary.  If | ||||
| @@ -251,7 +251,7 @@ __pthread_rwlock_rdunlock (pthread_rwlock_t *rwlock)
 | ||||
|  	 the first reader's store to __wrphase_futex (or a later value) if | ||||
|  	 the writer observes that a write phase has been started.  */ | ||||
|        if (atomic_compare_exchange_weak_release (&rwlock->__data.__readers, | ||||
| -	  &r, rnew))
 | ||||
| +						&r, rnew))
 | ||||
|  	break; | ||||
|        /* TODO Back-off.  */ | ||||
|      } | ||||
| @@ -285,7 +285,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|    /* Make sure we are not holding the rwlock as a writer.  This is a deadlock | ||||
|       situation we recognize and report.  */ | ||||
|    if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer) | ||||
| -      == THREAD_GETMEM (THREAD_SELF, tid)))
 | ||||
| +			== THREAD_GETMEM (THREAD_SELF, tid)))
 | ||||
|      return EDEADLK; | ||||
|   | ||||
|    /* If we prefer writers, recursive rdlock is disallowed, we are in a read | ||||
| @@ -299,9 +299,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|    if (rwlock->__data.__flags == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP) | ||||
|      { | ||||
|        r = atomic_load_relaxed (&rwlock->__data.__readers); | ||||
| -      while (((r & PTHREAD_RWLOCK_WRPHASE) == 0)
 | ||||
| -	      && ((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
 | ||||
| -	      && ((r >> PTHREAD_RWLOCK_READER_SHIFT) > 0))
 | ||||
| +      while ((r & PTHREAD_RWLOCK_WRPHASE) == 0
 | ||||
| +	     && (r & PTHREAD_RWLOCK_WRLOCKED) != 0
 | ||||
| +	     && (r >> PTHREAD_RWLOCK_READER_SHIFT) > 0)
 | ||||
|  	{ | ||||
|  	  /* TODO Spin first.  */ | ||||
|  	  /* Try setting the flag signaling that we are waiting without having | ||||
| @@ -315,11 +315,11 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  		 __readers, and all threads set the flag under the same | ||||
|  		 conditions.  */ | ||||
|  	      while ((atomic_load_relaxed (&rwlock->__data.__readers) | ||||
| -		  & PTHREAD_RWLOCK_RWAITING) != 0)
 | ||||
| +		      & PTHREAD_RWLOCK_RWAITING) != 0)
 | ||||
|  		{ | ||||
|  		  int private = __pthread_rwlock_get_private (rwlock); | ||||
|  		  int err = futex_abstimed_wait (&rwlock->__data.__readers, | ||||
| -		      r, abstime, private);
 | ||||
| +						 r, abstime, private);
 | ||||
|  		  /* We ignore EAGAIN and EINTR.  On time-outs, we can just | ||||
|  		     return because we don't need to clean up anything.  */ | ||||
|  		  if (err == ETIMEDOUT) | ||||
| @@ -338,8 +338,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|       expected value for future operations.  Acquire MO so we synchronize with | ||||
|       prior writers as well as the last reader of the previous read phase (see | ||||
|       below).  */ | ||||
| -  r = atomic_fetch_add_acquire (&rwlock->__data.__readers,
 | ||||
| -      (1 << PTHREAD_RWLOCK_READER_SHIFT)) + (1 << PTHREAD_RWLOCK_READER_SHIFT);
 | ||||
| +  r = (atomic_fetch_add_acquire (&rwlock->__data.__readers,
 | ||||
| +				 (1 << PTHREAD_RWLOCK_READER_SHIFT))
 | ||||
| +       + (1 << PTHREAD_RWLOCK_READER_SHIFT));
 | ||||
|   | ||||
|    /* Check whether there is an overflow in the number of readers.  We assume | ||||
|       that the total number of threads is less than half the maximum number | ||||
| @@ -359,8 +360,9 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|        /* Relaxed MO is okay because we just want to undo our registration and | ||||
|  	 cannot have changed the rwlock state substantially if the CAS | ||||
|  	 succeeds.  */ | ||||
| -      if (atomic_compare_exchange_weak_relaxed (&rwlock->__data.__readers, &r,
 | ||||
| -	  r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
 | ||||
| +      if (atomic_compare_exchange_weak_relaxed
 | ||||
| +	  (&rwlock->__data.__readers,
 | ||||
| +	   &r, r - (1 << PTHREAD_RWLOCK_READER_SHIFT)))
 | ||||
|  	return EAGAIN; | ||||
|      } | ||||
|   | ||||
| @@ -378,15 +380,15 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|    /* Otherwise, if we were in a write phase (states #6 or #8), we must wait | ||||
|       for explicit hand-over of the read phase; the only exception is if we | ||||
|       can start a read phase if there is no primary writer currently.  */ | ||||
| -  while (((r & PTHREAD_RWLOCK_WRPHASE) != 0)
 | ||||
| -      && ((r & PTHREAD_RWLOCK_WRLOCKED) == 0))
 | ||||
| +  while ((r & PTHREAD_RWLOCK_WRPHASE) != 0
 | ||||
| +	 && (r & PTHREAD_RWLOCK_WRLOCKED) == 0)
 | ||||
|      { | ||||
| -       /* Try to enter a read phase: If the CAS below succeeds, we have
 | ||||
| +      /* Try to enter a read phase: If the CAS below succeeds, we have
 | ||||
|  	 ownership; if it fails, we will simply retry and reassess the | ||||
|  	 situation. | ||||
|  	 Acquire MO so we synchronize with prior writers.  */ | ||||
|        if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r, | ||||
| -	  r ^ PTHREAD_RWLOCK_WRPHASE))
 | ||||
| +						r ^ PTHREAD_RWLOCK_WRPHASE))
 | ||||
|  	{ | ||||
|  	  /* We started the read phase, so we are also responsible for | ||||
|  	     updating the write-phase futex.  Relaxed MO is sufficient. | ||||
| @@ -397,7 +399,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	     (but we can pretend to do the setting and unsetting of WRLOCKED | ||||
|  	     atomically, and thus can skip this step).  */ | ||||
|  	  if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0) | ||||
| -	      & PTHREAD_RWLOCK_FUTEX_USED) != 0)
 | ||||
| +	       & PTHREAD_RWLOCK_FUTEX_USED) != 0)
 | ||||
|  	    { | ||||
|  	      int private = __pthread_rwlock_get_private (rwlock); | ||||
|  	      futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private); | ||||
| @@ -435,16 +437,17 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|    for (;;) | ||||
|      { | ||||
|        while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) | ||||
| -	  | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
| +	      | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
|  	{ | ||||
|  	  int private = __pthread_rwlock_get_private (rwlock); | ||||
|  	  if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0) | ||||
| -	      && !atomic_compare_exchange_weak_relaxed
 | ||||
| +	      && (!atomic_compare_exchange_weak_relaxed
 | ||||
|  		  (&rwlock->__data.__wrphase_futex, | ||||
| -		   &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
| +		   &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
 | ||||
|  	    continue; | ||||
|  	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, | ||||
| -	      1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
 | ||||
| +					 1 | PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +					 abstime, private);
 | ||||
|  	  if (err == ETIMEDOUT) | ||||
|  	    { | ||||
|  	      /* If we timed out, we need to unregister.  If no read phase | ||||
| @@ -477,8 +480,8 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  		 in this case and thus make the spin-waiting we need | ||||
|  		 unnecessarily expensive.  */ | ||||
|  	      while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex) | ||||
| -		  | PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
| -		  == (1 | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
| +		      | PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
| +		     == (1 | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
|  		{ | ||||
|  		  /* TODO Back-off?  */ | ||||
|  		} | ||||
| @@ -495,7 +498,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	 release of the writer, and so that we observe a recent value of | ||||
|  	 __wrphase_futex (see below).  */ | ||||
|        if ((atomic_load_acquire (&rwlock->__data.__readers) | ||||
| -	  & PTHREAD_RWLOCK_WRPHASE) == 0)
 | ||||
| +	   & PTHREAD_RWLOCK_WRPHASE) == 0)
 | ||||
|  	/* We are in a read phase now, so the least recent modification of | ||||
|  	   __wrphase_futex we can read from is the store by the writer | ||||
|  	   with value 1.  Thus, only now we can assume that if we observe | ||||
| @@ -516,8 +519,9 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock)
 | ||||
|    atomic_store_relaxed (&rwlock->__data.__cur_writer, 0); | ||||
|    /* Disable waiting by writers.  We will wake up after we decided how to | ||||
|       proceed.  */ | ||||
| -  bool wake_writers = ((atomic_exchange_relaxed
 | ||||
| -      (&rwlock->__data.__writers_futex, 0) & PTHREAD_RWLOCK_FUTEX_USED) != 0);
 | ||||
| +  bool wake_writers
 | ||||
| +    = ((atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0)
 | ||||
| +	& PTHREAD_RWLOCK_FUTEX_USED) != 0);
 | ||||
|   | ||||
|    if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP) | ||||
|      { | ||||
| @@ -529,8 +533,8 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock)
 | ||||
|  	     synchronize with us and thus can take over our view of | ||||
|  	     __readers (including, for example, whether we are in a write | ||||
|  	     phase or not).  */ | ||||
| -	  if (atomic_compare_exchange_weak_release (&rwlock->__data.__writers,
 | ||||
| -	      &w, w | PTHREAD_RWLOCK_WRHANDOVER))
 | ||||
| +	  if (atomic_compare_exchange_weak_release
 | ||||
| +	      (&rwlock->__data.__writers, &w, w | PTHREAD_RWLOCK_WRHANDOVER))
 | ||||
|  	    /* Another writer will take over.  */ | ||||
|  	    goto done; | ||||
|  	  /* TODO Back-off.  */ | ||||
| @@ -543,9 +547,10 @@ __pthread_rwlock_wrunlock (pthread_rwlock_t *rwlock)
 | ||||
|    unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers); | ||||
|    /* Release MO so that subsequent readers or writers synchronize with us.  */ | ||||
|    while (!atomic_compare_exchange_weak_release | ||||
| -      (&rwlock->__data.__readers, &r, (r ^ PTHREAD_RWLOCK_WRLOCKED)
 | ||||
| -	  ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
 | ||||
| -	      : PTHREAD_RWLOCK_WRPHASE)))
 | ||||
| +	 (&rwlock->__data.__readers, &r,
 | ||||
| +	  ((r ^ PTHREAD_RWLOCK_WRLOCKED)
 | ||||
| +	   ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
 | ||||
| +	      : PTHREAD_RWLOCK_WRPHASE))))
 | ||||
|      { | ||||
|        /* TODO Back-off.  */ | ||||
|      } | ||||
| @@ -574,7 +579,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|    /* Make sure we are not holding the rwlock as a writer.  This is a deadlock | ||||
|       situation we recognize and report.  */ | ||||
|    if (__glibc_unlikely (atomic_load_relaxed (&rwlock->__data.__cur_writer) | ||||
| -      == THREAD_GETMEM (THREAD_SELF, tid)))
 | ||||
| +			== THREAD_GETMEM (THREAD_SELF, tid)))
 | ||||
|      return EDEADLK; | ||||
|   | ||||
|    /* First we try to acquire the role of primary writer by setting WRLOCKED; | ||||
| @@ -593,12 +598,12 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|       this could be less scalable if readers arrive and leave frequently.  */ | ||||
|    bool may_share_futex_used_flag = false; | ||||
|    unsigned int r = atomic_fetch_or_acquire (&rwlock->__data.__readers, | ||||
| -      PTHREAD_RWLOCK_WRLOCKED);
 | ||||
| +					    PTHREAD_RWLOCK_WRLOCKED);
 | ||||
|    if (__glibc_unlikely ((r & PTHREAD_RWLOCK_WRLOCKED) != 0)) | ||||
|      { | ||||
|        /* There is another primary writer.  */ | ||||
| -      bool prefer_writer =
 | ||||
| -	  (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP);
 | ||||
| +      bool prefer_writer
 | ||||
| +	= (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP);
 | ||||
|        if (prefer_writer) | ||||
|  	{ | ||||
|  	  /* We register as a waiting writer, so that we can make use of | ||||
| @@ -617,8 +622,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	      /* Try to become the primary writer or retry.  Acquire MO as in | ||||
|  		 the fetch_or above.  */ | ||||
|  	      if (atomic_compare_exchange_weak_acquire | ||||
| -		  (&rwlock->__data.__readers, &r,
 | ||||
| -		      r | PTHREAD_RWLOCK_WRLOCKED))
 | ||||
| +		  (&rwlock->__data.__readers, &r, r | PTHREAD_RWLOCK_WRLOCKED))
 | ||||
|  		{ | ||||
|  		  if (prefer_writer) | ||||
|  		    { | ||||
| @@ -633,8 +637,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  			 __writers). | ||||
|  			 ??? Perhaps this is not strictly necessary for | ||||
|  			 reasons we do not yet know of.  */ | ||||
| -		      atomic_fetch_add_relaxed (&rwlock->__data.__writers,
 | ||||
| -			  -1);
 | ||||
| +		      atomic_fetch_add_relaxed (&rwlock->__data.__writers, -1);
 | ||||
|  		    } | ||||
|  		  break; | ||||
|  		} | ||||
| @@ -646,8 +649,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	     succeed, we own WRLOCKED.  */ | ||||
|  	  if (prefer_writer) | ||||
|  	    { | ||||
| -	      unsigned int w = atomic_load_relaxed
 | ||||
| -		  (&rwlock->__data.__writers);
 | ||||
| +	      unsigned int w = atomic_load_relaxed (&rwlock->__data.__writers);
 | ||||
|  	      if ((w & PTHREAD_RWLOCK_WRHANDOVER) != 0) | ||||
|  		{ | ||||
|  		  /* Acquire MO is required here so that we synchronize with | ||||
| @@ -677,13 +679,13 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	  /* We did not acquire WRLOCKED nor were able to use writer--writer | ||||
|  	     hand-over, so we block on __writers_futex.  */ | ||||
|  	  int private = __pthread_rwlock_get_private (rwlock); | ||||
| -	  unsigned int wf = atomic_load_relaxed
 | ||||
| -	      (&rwlock->__data.__writers_futex);
 | ||||
| +	  unsigned int wf
 | ||||
| +	    = atomic_load_relaxed (&rwlock->__data.__writers_futex);
 | ||||
|  	  if (((wf & ~(unsigned int) PTHREAD_RWLOCK_FUTEX_USED) != 1) | ||||
|  	      || ((wf != (1 | PTHREAD_RWLOCK_FUTEX_USED)) | ||||
| -		  && !atomic_compare_exchange_weak_relaxed
 | ||||
| +		  && (!atomic_compare_exchange_weak_relaxed
 | ||||
|  		      (&rwlock->__data.__writers_futex, &wf, | ||||
| -		       1 | PTHREAD_RWLOCK_FUTEX_USED)))
 | ||||
| +		       1 | PTHREAD_RWLOCK_FUTEX_USED))))
 | ||||
|  	    { | ||||
|  	      /* If we cannot block on __writers_futex because there is no | ||||
|  		 primary writer, or we cannot set PTHREAD_RWLOCK_FUTEX_USED, | ||||
| @@ -704,7 +706,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	     in this group.  */ | ||||
|  	  may_share_futex_used_flag = true; | ||||
|  	  int err = futex_abstimed_wait (&rwlock->__data.__writers_futex, | ||||
| -	      1 | PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
 | ||||
| +					 1 | PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +					 abstime, private);
 | ||||
|  	  if (err == ETIMEDOUT) | ||||
|  	    { | ||||
|  	      if (prefer_writer) | ||||
| @@ -716,10 +719,10 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  		     that this happened before the timeout; see | ||||
|  		     pthread_rwlock_rdlock_full for the full reasoning.) | ||||
|  		     Also see the similar code above.  */ | ||||
| -		  unsigned int w = atomic_load_relaxed
 | ||||
| -		      (&rwlock->__data.__writers);
 | ||||
| +		  unsigned int w
 | ||||
| +		    = atomic_load_relaxed (&rwlock->__data.__writers);
 | ||||
|  		  while (!atomic_compare_exchange_weak_acquire | ||||
| -		      (&rwlock->__data.__writers, &w,
 | ||||
| +			 (&rwlock->__data.__writers, &w,
 | ||||
|  			  (w == PTHREAD_RWLOCK_WRHANDOVER + 1 ? 0 : w - 1))) | ||||
|  		    { | ||||
|  		      /* TODO Back-off.  */ | ||||
| @@ -751,7 +754,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|       modifications of __readers ensures that this store happens after the | ||||
|       store of value 0 by the previous primary writer.  */ | ||||
|    atomic_store_relaxed (&rwlock->__data.__writers_futex, | ||||
| -      1 | (may_share_futex_used_flag ? PTHREAD_RWLOCK_FUTEX_USED : 0));
 | ||||
| +			1 | (may_share_futex_used_flag
 | ||||
| +			     ? PTHREAD_RWLOCK_FUTEX_USED : 0));
 | ||||
|   | ||||
|    /* If we are in a write phase, we have acquired the lock.  */ | ||||
|    if ((r & PTHREAD_RWLOCK_WRPHASE) != 0) | ||||
| @@ -759,15 +763,15 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|   | ||||
|    /* If we are in a read phase and there are no readers, try to start a write | ||||
|       phase.  */ | ||||
| -  while (((r & PTHREAD_RWLOCK_WRPHASE) == 0)
 | ||||
| -      && ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0))
 | ||||
| +  while ((r & PTHREAD_RWLOCK_WRPHASE) == 0
 | ||||
| +	 && (r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
 | ||||
|      { | ||||
|        /* Acquire MO so that we synchronize with prior writers and do | ||||
|  	 not interfere with their updates to __writers_futex, as well | ||||
|  	 as regarding prior readers and their updates to __wrphase_futex, | ||||
|  	 respectively.  */ | ||||
|        if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, | ||||
| -	  &r, r | PTHREAD_RWLOCK_WRPHASE))
 | ||||
| +						&r, r | PTHREAD_RWLOCK_WRPHASE))
 | ||||
|  	{ | ||||
|  	  /* We have started a write phase, so need to enable readers to wait. | ||||
|  	     See the similar case in __pthread_rwlock_rdlock_full.  Unlike in | ||||
| @@ -792,24 +796,24 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|    for (;;) | ||||
|      { | ||||
|        while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex)) | ||||
| -	  | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
| +	      | PTHREAD_RWLOCK_FUTEX_USED) == PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
|  	{ | ||||
|  	  int private = __pthread_rwlock_get_private (rwlock); | ||||
| -	  if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
 | ||||
| -	      && !atomic_compare_exchange_weak_relaxed
 | ||||
| +	  if ((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0
 | ||||
| +	      && (!atomic_compare_exchange_weak_relaxed
 | ||||
|  		  (&rwlock->__data.__wrphase_futex, &wpf, | ||||
| -		   PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
| +		   PTHREAD_RWLOCK_FUTEX_USED)))
 | ||||
|  	    continue; | ||||
|  	  int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex, | ||||
| -	      PTHREAD_RWLOCK_FUTEX_USED, abstime, private);
 | ||||
| +					 PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +					 abstime, private);
 | ||||
|  	  if (err == ETIMEDOUT) | ||||
|  	    { | ||||
| -	      if (rwlock->__data.__flags
 | ||||
| -		  != PTHREAD_RWLOCK_PREFER_READER_NP)
 | ||||
| +	      if (rwlock->__data.__flags != PTHREAD_RWLOCK_PREFER_READER_NP)
 | ||||
|  		{ | ||||
|  		  /* We try writer--writer hand-over.  */ | ||||
| -		  unsigned int w = atomic_load_relaxed
 | ||||
| -		      (&rwlock->__data.__writers);
 | ||||
| +		  unsigned int w
 | ||||
| +		    = atomic_load_relaxed (&rwlock->__data.__writers);
 | ||||
|  		  if (w != 0) | ||||
|  		    { | ||||
|  		      /* We are about to hand over WRLOCKED, so we must | ||||
| @@ -823,13 +827,13 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  			 Release MO so that another writer that gets | ||||
|  			 WRLOCKED from us can take over our view of | ||||
|  			 __readers.  */ | ||||
| -		      unsigned int wf = atomic_exchange_relaxed
 | ||||
| -			  (&rwlock->__data.__writers_futex, 0);
 | ||||
| +		      unsigned int wf
 | ||||
| +			= atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0);
 | ||||
|  		      while (w != 0) | ||||
|  			{ | ||||
|  			  if (atomic_compare_exchange_weak_release | ||||
|  			      (&rwlock->__data.__writers, &w, | ||||
| -				  w | PTHREAD_RWLOCK_WRHANDOVER))
 | ||||
| +			       w | PTHREAD_RWLOCK_WRHANDOVER))
 | ||||
|  			    { | ||||
|  			      /* Wake other writers.  */ | ||||
|  			      if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0) | ||||
| @@ -844,8 +848,7 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  			 again.  Make sure we don't loose the flag that | ||||
|  			 signals whether there are threads waiting on | ||||
|  			 this futex.  */ | ||||
| -		      atomic_store_relaxed
 | ||||
| -			  (&rwlock->__data.__writers_futex, wf);
 | ||||
| +		      atomic_store_relaxed (&rwlock->__data.__writers_futex, wf);
 | ||||
|  		    } | ||||
|  		} | ||||
|  	      /* If we timed out and we are not in a write phase, we can | ||||
| @@ -857,8 +860,8 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  		  /* We are about to release WRLOCKED, so we must release | ||||
|  		     __writers_futex too; see the handling of | ||||
|  		     writer--writer hand-over above.  */ | ||||
| -		  unsigned int wf = atomic_exchange_relaxed
 | ||||
| -		      (&rwlock->__data.__writers_futex, 0);
 | ||||
| +		  unsigned int wf
 | ||||
| +		    = atomic_exchange_relaxed (&rwlock->__data.__writers_futex, 0);
 | ||||
|  		  while ((r & PTHREAD_RWLOCK_WRPHASE) == 0) | ||||
|  		    { | ||||
|  		      /* While we don't need to make anything from a | ||||
| @@ -877,11 +880,11 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  			  /* Wake other writers.  */ | ||||
|  			  if ((wf & PTHREAD_RWLOCK_FUTEX_USED) != 0) | ||||
|  			    futex_wake (&rwlock->__data.__writers_futex, | ||||
| -				1, private);
 | ||||
| +					1, private);
 | ||||
|  			  /* Wake waiting readers.  */ | ||||
|  			  if ((r & PTHREAD_RWLOCK_RWAITING) != 0) | ||||
|  			    futex_wake (&rwlock->__data.__readers, | ||||
| -				INT_MAX, private);
 | ||||
| +					INT_MAX, private);
 | ||||
|  			  return ETIMEDOUT; | ||||
|  			} | ||||
|  		    } | ||||
| @@ -898,10 +901,9 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  	      atomic_thread_fence_acquire (); | ||||
|  	      /* We still need to wait for explicit hand-over, but we must | ||||
|  		 not use futex_wait anymore.  */ | ||||
| -	      while ((atomic_load_relaxed
 | ||||
| -		  (&rwlock->__data.__wrphase_futex)
 | ||||
| -		   | PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
| -		  == PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
| +	      while ((atomic_load_relaxed (&rwlock->__data.__wrphase_futex)
 | ||||
| +		      | PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
| +		     == PTHREAD_RWLOCK_FUTEX_USED)
 | ||||
|  		{ | ||||
|  		  /* TODO Back-off.  */ | ||||
|  		} | ||||
| @@ -915,12 +917,12 @@ __pthread_rwlock_wrlock_full (pthread_rwlock_t *rwlock,
 | ||||
|        if (ready) | ||||
|  	break; | ||||
|        if ((atomic_load_acquire (&rwlock->__data.__readers) | ||||
| -	  & PTHREAD_RWLOCK_WRPHASE) != 0)
 | ||||
| +	   & PTHREAD_RWLOCK_WRPHASE) != 0)
 | ||||
|  	ready = true; | ||||
|      } | ||||
|   | ||||
|   done: | ||||
|    atomic_store_relaxed (&rwlock->__data.__cur_writer, | ||||
| -      THREAD_GETMEM (THREAD_SELF, tid));
 | ||||
| +			THREAD_GETMEM (THREAD_SELF, tid));
 | ||||
|    return 0; | ||||
|  } | ||||
							
								
								
									
										134
									
								
								SOURCES/glibc-rh1654872-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								SOURCES/glibc-rh1654872-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | ||||
| commit f21e8f8ca466320fed38bdb71526c574dae98026 | ||||
| Author: Andreas Schwab <schwab@suse.de> | ||||
| Date:   Thu Nov 8 14:28:22 2018 +0100 | ||||
| 
 | ||||
|     Fix rwlock stall with PREFER_WRITER_NONRECURSIVE_NP (bug 23861) | ||||
|      | ||||
|     In the read lock function (__pthread_rwlock_rdlock_full) there was a | ||||
|     code path which would fail to reload __readers while waiting for | ||||
|     PTHREAD_RWLOCK_RWAITING to change. This failure to reload __readers | ||||
|     into a local value meant that various conditionals used the old value | ||||
|     of __readers and with only two threads left it could result in an | ||||
|     indefinite stall of one of the readers (waiting for PTHREAD_RWLOCK_RWAITING | ||||
|     to go to zero, but it never would). | ||||
| 
 | ||||
| diff --git a/nptl/Makefile b/nptl/Makefile
 | ||||
| index ee720960d18f33d1..2d2db648f730db61 100644
 | ||||
| --- a/nptl/Makefile
 | ||||
| +++ b/nptl/Makefile
 | ||||
| @@ -318,7 +318,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
 | ||||
|  	tst-minstack-throw \ | ||||
|  	tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ | ||||
|  	tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \ | ||||
| -	tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock
 | ||||
| +	tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \
 | ||||
| +	tst-rwlock-pwn
 | ||||
|   | ||||
|  tests-internal := tst-rwlock19 tst-rwlock20 \ | ||||
|  		  tst-sem11 tst-sem12 tst-sem13 \ | ||||
| diff --git a/nptl/pthread_rwlock_common.c b/nptl/pthread_rwlock_common.c
 | ||||
| index 5dd534271aed6b41..85fc1bcfc7f5e60d 100644
 | ||||
| --- a/nptl/pthread_rwlock_common.c
 | ||||
| +++ b/nptl/pthread_rwlock_common.c
 | ||||
| @@ -314,7 +314,7 @@ __pthread_rwlock_rdlock_full (pthread_rwlock_t *rwlock,
 | ||||
|  		 harmless because the flag is just about the state of | ||||
|  		 __readers, and all threads set the flag under the same | ||||
|  		 conditions.  */ | ||||
| -	      while ((atomic_load_relaxed (&rwlock->__data.__readers)
 | ||||
| +	      while (((r = atomic_load_relaxed (&rwlock->__data.__readers))
 | ||||
|  		      & PTHREAD_RWLOCK_RWAITING) != 0) | ||||
|  		{ | ||||
|  		  int private = __pthread_rwlock_get_private (rwlock); | ||||
| diff --git a/nptl/tst-rwlock-pwn.c b/nptl/tst-rwlock-pwn.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..c39dd70973f1a76e
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-rwlock-pwn.c
 | ||||
| @@ -0,0 +1,87 @@
 | ||||
| +/* Test rwlock with PREFER_WRITER_NONRECURSIVE_NP (bug 23861).
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#include <pthread.h>
 | ||||
| +#include <support/xthread.h>
 | ||||
| +
 | ||||
| +/* We choose 10 iterations because this happens to be able to trigger the
 | ||||
| +   stall on contemporary hardware.  */
 | ||||
| +#define LOOPS 10
 | ||||
| +/* We need 3 threads to trigger bug 23861.  One thread as a writer, and
 | ||||
| +   two reader threads.  The test verifies that the second-to-last reader
 | ||||
| +   is able to notify the *last* reader that it should be done waiting.
 | ||||
| +   If the second-to-last reader fails to notify the last reader or does
 | ||||
| +   so incorrectly then the last reader may stall indefinitely.  */
 | ||||
| +#define NTHREADS 3
 | ||||
| +
 | ||||
| +_Atomic int do_exit;
 | ||||
| +pthread_rwlockattr_t mylock_attr;
 | ||||
| +pthread_rwlock_t mylock;
 | ||||
| +
 | ||||
| +void *
 | ||||
| +run_loop (void *a)
 | ||||
| +{
 | ||||
| +  while (!do_exit)
 | ||||
| +    {
 | ||||
| +      if (random () & 1)
 | ||||
| +	{
 | ||||
| +	  xpthread_rwlock_wrlock (&mylock);
 | ||||
| +	  xpthread_rwlock_unlock (&mylock);
 | ||||
| +	}
 | ||||
| +      else
 | ||||
| +	{
 | ||||
| +	  xpthread_rwlock_rdlock (&mylock);
 | ||||
| +	  xpthread_rwlock_unlock (&mylock);
 | ||||
| +	}
 | ||||
| +    }
 | ||||
| +  return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  xpthread_rwlockattr_init (&mylock_attr);
 | ||||
| +  xpthread_rwlockattr_setkind_np (&mylock_attr,
 | ||||
| +				  PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
 | ||||
| +  xpthread_rwlock_init (&mylock, &mylock_attr);
 | ||||
| +
 | ||||
| +  for (int n = 0; n < LOOPS; n++)
 | ||||
| +    {
 | ||||
| +      pthread_t tids[NTHREADS];
 | ||||
| +      do_exit = 0;
 | ||||
| +      for (int i = 0; i < NTHREADS; i++)
 | ||||
| +	tids[i] = xpthread_create (NULL, run_loop, NULL);
 | ||||
| +      /* Let the threads run for some time.  */
 | ||||
| +      sleep (1);
 | ||||
| +      printf ("Exiting...");
 | ||||
| +      fflush (stdout);
 | ||||
| +      do_exit = 1;
 | ||||
| +      for (int i = 0; i < NTHREADS; i++)
 | ||||
| +	xpthread_join (tids[i]);
 | ||||
| +      printf ("done.\n");
 | ||||
| +    }
 | ||||
| +  pthread_rwlock_destroy (&mylock);
 | ||||
| +  pthread_rwlockattr_destroy (&mylock_attr);
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define TIMEOUT (DEFAULT_TIMEOUT + 3 * LOOPS)
 | ||||
| +#include <support/test-driver.c>
 | ||||
							
								
								
									
										140
									
								
								SOURCES/glibc-rh1658901.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								SOURCES/glibc-rh1658901.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,140 @@ | ||||
| Upstream commit 1d880d4a9bf7608c2cd33bbe954ce6995f79121a | ||||
| 
 | ||||
| From: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | ||||
| Date: Wed, 12 Dec 2018 12:41:52 +0000 (-0200) | ||||
| Subject: powerpc: Add missing CFI register information (bug #23614) | ||||
| X-Git-Tag: glibc-2.29~210 | ||||
| X-Git-Url: https://sourceware.org/git/?p=glibc.git;a=commitdiff_plain;h=1d880d4a9bf7608c2cd33bbe954ce6995f79121a | ||||
| 
 | ||||
| powerpc: Add missing CFI register information (bug #23614) | ||||
| 
 | ||||
| Add CFI information about the offset of registers stored in the stack | ||||
| frame. | ||||
| 
 | ||||
| 	[BZ #23614] | ||||
| 	* sysdeps/powerpc/powerpc64/addmul_1.S (FUNC): Add CFI offset for | ||||
| 	registers saved in the stack frame. | ||||
| 	* sysdeps/powerpc/powerpc64/lshift.S (__mpn_lshift): Likewise. | ||||
| 	* sysdeps/powerpc/powerpc64/mul_1.S (__mpn_mul_1): Likewise. | ||||
| 
 | ||||
| Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com> | ||||
| Reviewed-by: Gabriel F. T. Gomes <gabriel@inconstante.eti.br> | ||||
| ---
 | ||||
| 
 | ||||
| diff --git a/sysdeps/powerpc/powerpc64/addmul_1.S b/sysdeps/powerpc/powerpc64/addmul_1.S
 | ||||
| index 48e3b1b..e450d6a 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc64/addmul_1.S
 | ||||
| +++ b/sysdeps/powerpc/powerpc64/addmul_1.S
 | ||||
| @@ -34,16 +34,27 @@
 | ||||
|  #define N   r5 | ||||
|  #define VL  r6 | ||||
|   | ||||
| +#define R27SAVE  (-40)
 | ||||
| +#define R28SAVE  (-32)
 | ||||
| +#define R29SAVE  (-24)
 | ||||
| +#define R30SAVE  (-16)
 | ||||
| +#define R31SAVE  (-8)
 | ||||
| +
 | ||||
|  ENTRY_TOCLESS (FUNC, 5) | ||||
| -	std	r31, -8(r1)
 | ||||
| +	std	r31, R31SAVE(r1)
 | ||||
|  	rldicl.	r0, N, 0, 62 | ||||
| -	std	r30, -16(r1)
 | ||||
| +	std	r30, R30SAVE(r1)
 | ||||
|  	cmpdi	VL, r0, 2 | ||||
| -	std	r29, -24(r1)
 | ||||
| +	std	r29, R29SAVE(r1)
 | ||||
|  	addi	N, N, 3 | ||||
| -	std	r28, -32(r1)
 | ||||
| +	std	r28, R28SAVE(r1)
 | ||||
|  	srdi	N, N, 2 | ||||
| -	std	r27, -40(r1)
 | ||||
| +	std	r27, R27SAVE(r1)
 | ||||
| +	cfi_offset(r31, R31SAVE)
 | ||||
| +	cfi_offset(r30, R30SAVE)
 | ||||
| +	cfi_offset(r29, R29SAVE)
 | ||||
| +	cfi_offset(r28, R28SAVE)
 | ||||
| +	cfi_offset(r27, R27SAVE)
 | ||||
|  	mtctr	N | ||||
|  	beq	cr0, L(b00) | ||||
|  	blt	cr6, L(b01) | ||||
| @@ -199,10 +210,10 @@ L(end):	mulld	r0, r9, VL
 | ||||
|  	addic	r11, r11, 1 | ||||
|  #endif | ||||
|  	addze	RP, r8 | ||||
| -	ld	r31, -8(r1)
 | ||||
| -	ld	r30, -16(r1)
 | ||||
| -	ld	r29, -24(r1)
 | ||||
| -	ld	r28, -32(r1)
 | ||||
| -	ld	r27, -40(r1)
 | ||||
| +	ld	r31, R31SAVE(r1)
 | ||||
| +	ld	r30, R30SAVE(r1)
 | ||||
| +	ld	r29, R29SAVE(r1)
 | ||||
| +	ld	r28, R28SAVE(r1)
 | ||||
| +	ld	r27, R27SAVE(r1)
 | ||||
|  	blr | ||||
|  END(FUNC) | ||||
| diff --git a/sysdeps/powerpc/powerpc64/lshift.S b/sysdeps/powerpc/powerpc64/lshift.S
 | ||||
| index 8b6396e..855d6f2 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc64/lshift.S
 | ||||
| +++ b/sysdeps/powerpc/powerpc64/lshift.S
 | ||||
| @@ -26,11 +26,15 @@
 | ||||
|  #define TNC      r0 | ||||
|  #define U0      r30 | ||||
|  #define U1      r31 | ||||
| +#define U0SAVE  (-16)
 | ||||
| +#define U1SAVE  (-8)
 | ||||
|  #define RETVAL   r5 | ||||
|   | ||||
|  ENTRY_TOCLESS (__mpn_lshift, 5) | ||||
| -	std	U1, -8(r1)
 | ||||
| -	std	U0, -16(r1)
 | ||||
| +	std	U1, U1SAVE(r1)
 | ||||
| +	std	U0, U0SAVE(r1)
 | ||||
| +	cfi_offset(U1, U1SAVE)
 | ||||
| +	cfi_offset(U0, U0SAVE)
 | ||||
|  	subfic	TNC, CNT, 64 | ||||
|  	sldi	r7, N, RP | ||||
|  	add	UP, UP, r7 | ||||
| @@ -170,8 +174,8 @@ L(cj3):	or	r10, r12, r7
 | ||||
|  L(cj2):	std	r10, -32(RP) | ||||
|  	std	r8, -40(RP) | ||||
|   | ||||
| -L(ret):	ld	U1, -8(r1)
 | ||||
| -	ld	U0, -16(r1)
 | ||||
| +L(ret):	ld	U1, U1SAVE(r1)
 | ||||
| +	ld	U0, U0SAVE(r1)
 | ||||
|  	mr	RP, RETVAL | ||||
|  	blr | ||||
|  END(__mpn_lshift) | ||||
| diff --git a/sysdeps/powerpc/powerpc64/mul_1.S b/sysdeps/powerpc/powerpc64/mul_1.S
 | ||||
| index 953ded8..cade365 100644
 | ||||
| --- a/sysdeps/powerpc/powerpc64/mul_1.S
 | ||||
| +++ b/sysdeps/powerpc/powerpc64/mul_1.S
 | ||||
| @@ -24,9 +24,14 @@
 | ||||
|  #define N   r5 | ||||
|  #define VL  r6 | ||||
|   | ||||
| +#define R26SAVE  (-48)
 | ||||
| +#define R27SAVE  (-40)
 | ||||
| +
 | ||||
|  ENTRY_TOCLESS (__mpn_mul_1, 5) | ||||
| -	std	r27, -40(r1)
 | ||||
| -	std	r26, -48(r1)
 | ||||
| +	std	r27, R27SAVE(r1)
 | ||||
| +	std	r26, R26SAVE(r1)
 | ||||
| +	cfi_offset(r27, R27SAVE)
 | ||||
| +	cfi_offset(r26, R26SAVE)
 | ||||
|  	li	r12, 0 | ||||
|  	ld	r26, 0(UP) | ||||
|   | ||||
| @@ -129,7 +134,7 @@ L(end):	mulld	r0, r26, VL
 | ||||
|  	std	r0, 0(RP) | ||||
|  	std	r7, 8(RP) | ||||
|  L(ret):	addze	RP, r8 | ||||
| -	ld	r27, -40(r1)
 | ||||
| -	ld	r26, -48(r1)
 | ||||
| +	ld	r27, R27SAVE(r1)
 | ||||
| +	ld	r26, R26SAVE(r1)
 | ||||
|  	blr | ||||
|  END(__mpn_mul_1) | ||||
							
								
								
									
										663
									
								
								SOURCES/glibc-rh1659293-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										663
									
								
								SOURCES/glibc-rh1659293-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,663 @@ | ||||
| nptl: Fix pthread_rwlock_try*lock stalls (Bug 23844) | ||||
| 
 | ||||
| For a full analysis of both the pthread_rwlock_tryrdlock() stall | ||||
| and the pthread_rwlock_trywrlock() stall see: | ||||
| https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14 | ||||
| 
 | ||||
| In the pthread_rwlock_trydlock() function we fail to inspect for | ||||
| PTHREAD_RWLOCK_FUTEX_USED in __wrphase_futex and wake the waiting | ||||
| readers. | ||||
| 
 | ||||
| In the pthread_rwlock_trywrlock() function we write 1 to | ||||
| __wrphase_futex and loose the setting of the PTHREAD_RWLOCK_FUTEX_USED | ||||
| bit, again failing to wake waiting readers during unlock. | ||||
| 
 | ||||
| The fix in the case of pthread_rwlock_trydlock() is to check for | ||||
| PTHREAD_RWLOCK_FUTEX_USED and wake the readers. | ||||
| 
 | ||||
| The fix in the case of pthread_rwlock_trywrlock() is to only write | ||||
| 1 to __wrphase_futex if we installed the write phase, since all other | ||||
| readers would be spinning waiting for this step. | ||||
| 
 | ||||
| We add two new tests, one exercises the stall for | ||||
| pthread_rwlock_trywrlock() which is easy to exercise, and one exercises | ||||
| the stall for pthread_rwlock_trydlock() which is harder to exercise. | ||||
| 
 | ||||
| The pthread_rwlock_trywrlock() test fails consistently without the fix, | ||||
| and passes after. The pthread_rwlock_tryrdlock() test fails roughly | ||||
| 5-10% of the time without the fix, and passes all the time after. | ||||
| 
 | ||||
| Signed-off-by: Carlos O'Donell <carlos@redhat.com> | ||||
| Signed-off-by: Torvald Riegel <triegel@redhat.com> | ||||
| Signed-off-by: Rik Prohaska <prohaska7@gmail.com> | ||||
| Co-authored-by: Torvald Riegel <triegel@redhat.com> | ||||
| Co-authored-by: Rik Prohaska <prohaska7@gmail.com> | ||||
| (cherry picked from commit 5fc9ed4c4058bfbdf51ad6e7aac7d209b580e8c4) | ||||
| 
 | ||||
| diff --git a/ChangeLog b/ChangeLog
 | ||||
| index 08b42bd2f56471e3..ed1a2ffe8356fd96 100644
 | ||||
| --- a/ChangeLog
 | ||||
| +++ b/ChangeLog
 | ||||
| @@ -1,3 +1,20 @@
 | ||||
| +2019-01-31  Carlos O'Donell  <carlos@redhat.com>
 | ||||
| +	    Torvald Riegel  <triegel@redhat.com>
 | ||||
| +	    Rik Prohaska  <prohaska7@gmail.com>
 | ||||
| +
 | ||||
| +	[BZ# 23844]
 | ||||
| +	* nptl/Makefile (tests): Add tst-rwlock-tryrdlock-stall, and
 | ||||
| +	tst-rwlock-trywrlock-stall.
 | ||||
| +	* nptl/pthread_rwlock_tryrdlock.c (__pthread_rwlock_tryrdlock):
 | ||||
| +	Wake waiters if PTHREAD_RWLOCK_FUTEX_USED is set.
 | ||||
| +	* nptl/pthread_rwlock_trywrlock.c (__pthread_rwlock_trywrlock):
 | ||||
| +	Set __wrphase_fute to 1 only if we started the write phase.
 | ||||
| +	* nptl/tst-rwlock-tryrdlock-stall.c: New file.
 | ||||
| +	* nptl/tst-rwlock-trywrlock-stall.c: New file.
 | ||||
| +	* support/Makefile (libsupport-routines): Add xpthread_rwlock_destroy.
 | ||||
| +	* support/xpthread_rwlock_destroy.c: New file.
 | ||||
| +	* support/xthread.h: Declare xpthread_rwlock_destroy.
 | ||||
| +
 | ||||
|  2018-08-01  Carlos O'Donel  <carlos@redhat.com> | ||||
|   | ||||
|  	* version.h (RELEASE): Set to "stable". | ||||
| diff --git a/nptl/Makefile b/nptl/Makefile
 | ||||
| index 2d2db648f730db61..b1003cf56b31ddfa 100644
 | ||||
| --- a/nptl/Makefile
 | ||||
| +++ b/nptl/Makefile
 | ||||
| @@ -319,7 +319,8 @@ tests = tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
 | ||||
|  	tst-cnd-basic tst-mtx-trylock tst-cnd-broadcast \ | ||||
|  	tst-cnd-timedwait tst-thrd-detach tst-mtx-basic tst-thrd-sleep \ | ||||
|  	tst-mtx-recursive tst-tss-basic tst-call-once tst-mtx-timedlock \ | ||||
| -	tst-rwlock-pwn
 | ||||
| +	tst-rwlock-pwn \
 | ||||
| +	tst-rwlock-tryrdlock-stall tst-rwlock-trywrlock-stall
 | ||||
|   | ||||
|  tests-internal := tst-rwlock19 tst-rwlock20 \ | ||||
|  		  tst-sem11 tst-sem12 tst-sem13 \ | ||||
| diff --git a/nptl/pthread_rwlock_tryrdlock.c b/nptl/pthread_rwlock_tryrdlock.c
 | ||||
| index 4aec1fc15acb2448..31a88d33a6e8f256 100644
 | ||||
| --- a/nptl/pthread_rwlock_tryrdlock.c
 | ||||
| +++ b/nptl/pthread_rwlock_tryrdlock.c
 | ||||
| @@ -94,15 +94,22 @@ __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
 | ||||
|        /* Same as in __pthread_rwlock_rdlock_full: | ||||
|  	 We started the read phase, so we are also responsible for | ||||
|  	 updating the write-phase futex.  Relaxed MO is sufficient. | ||||
| -	 Note that there can be no other reader that we have to wake
 | ||||
| -	 because all other readers will see the read phase started by us
 | ||||
| -	 (or they will try to start it themselves); if a writer started
 | ||||
| -	 the read phase, we cannot have started it.  Furthermore, we
 | ||||
| -	 cannot discard a PTHREAD_RWLOCK_FUTEX_USED flag because we will
 | ||||
| -	 overwrite the value set by the most recent writer (or the readers
 | ||||
| -	 before it in case of explicit hand-over) and we know that there
 | ||||
| -	 are no waiting readers.  */
 | ||||
| -      atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
 | ||||
| +	 We have to do the same steps as a writer would when handing over the
 | ||||
| +	 read phase to use because other readers cannot distinguish between
 | ||||
| +	 us and the writer.
 | ||||
| +	 Note that __pthread_rwlock_tryrdlock callers will not have to be
 | ||||
| +	 woken up because they will either see the read phase started by us
 | ||||
| +	 or they will try to start it themselves; however, callers of
 | ||||
| +	 __pthread_rwlock_rdlock_full just increase the reader count and then
 | ||||
| +	 check what state the lock is in, so they cannot distinguish between
 | ||||
| +	 us and a writer that acquired and released the lock in the
 | ||||
| +	 meantime.  */
 | ||||
| +      if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
 | ||||
| +	  & PTHREAD_RWLOCK_FUTEX_USED) != 0)
 | ||||
| +	{
 | ||||
| +	  int private = __pthread_rwlock_get_private (rwlock);
 | ||||
| +	  futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
 | ||||
| +	}
 | ||||
|      } | ||||
|   | ||||
|    return 0; | ||||
| diff --git a/nptl/pthread_rwlock_trywrlock.c b/nptl/pthread_rwlock_trywrlock.c
 | ||||
| index 5a73eba756077297..f2e3443466a2554f 100644
 | ||||
| --- a/nptl/pthread_rwlock_trywrlock.c
 | ||||
| +++ b/nptl/pthread_rwlock_trywrlock.c
 | ||||
| @@ -46,8 +46,15 @@ __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
 | ||||
|  	  &rwlock->__data.__readers, &r, | ||||
|  	  r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED)) | ||||
|  	{ | ||||
| +	  /* We have become the primary writer and we cannot have shared
 | ||||
| +	     the PTHREAD_RWLOCK_FUTEX_USED flag with someone else, so we
 | ||||
| +	     can simply enable blocking (see full wrlock code).  */
 | ||||
|  	  atomic_store_relaxed (&rwlock->__data.__writers_futex, 1); | ||||
| -	  atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
 | ||||
| +	  /* If we started a write phase, we need to enable readers to
 | ||||
| +	     wait.  If we did not, we must not change it because other threads
 | ||||
| +	     may have set the PTHREAD_RWLOCK_FUTEX_USED in the meantime.  */
 | ||||
| +	  if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
 | ||||
| +	    atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
 | ||||
|  	  atomic_store_relaxed (&rwlock->__data.__cur_writer, | ||||
|  	      THREAD_GETMEM (THREAD_SELF, tid)); | ||||
|  	  return 0; | ||||
| diff --git a/nptl/tst-rwlock-tryrdlock-stall.c b/nptl/tst-rwlock-tryrdlock-stall.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..5e476da2b8d00c6a
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-rwlock-tryrdlock-stall.c
 | ||||
| @@ -0,0 +1,355 @@
 | ||||
| +/* Bug 23844: Test for pthread_rwlock_tryrdlock stalls.
 | ||||
| +   Copyright (C) 2019 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* For a full analysis see comment:
 | ||||
| +   https://sourceware.org/bugzilla/show_bug.cgi?id=23844#c14
 | ||||
| +
 | ||||
| +   Provided here for reference:
 | ||||
| +
 | ||||
| +   --- Analysis of pthread_rwlock_tryrdlock() stall ---
 | ||||
| +   A read lock begins to execute.
 | ||||
| +
 | ||||
| +   In __pthread_rwlock_rdlock_full:
 | ||||
| +
 | ||||
| +   We can attempt a read lock, but find that the lock is
 | ||||
| +   in a write phase (PTHREAD_RWLOCK_WRPHASE, or WP-bit
 | ||||
| +   is set), and the lock is held by a primary writer
 | ||||
| +   (PTHREAD_RWLOCK_WRLOCKED is set). In this case we must
 | ||||
| +   wait for explicit hand over from the writer to us or
 | ||||
| +   one of the other waiters. The read lock threads are
 | ||||
| +   about to execute:
 | ||||
| +
 | ||||
| +   341   r = (atomic_fetch_add_acquire (&rwlock->__data.__readers,
 | ||||
| +   342                                  (1 << PTHREAD_RWLOCK_READER_SHIFT))
 | ||||
| +   343        + (1 << PTHREAD_RWLOCK_READER_SHIFT));
 | ||||
| +
 | ||||
| +   An unlock beings to execute.
 | ||||
| +
 | ||||
| +   Then in __pthread_rwlock_wrunlock:
 | ||||
| +
 | ||||
| +   547   unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
 | ||||
| +   ...
 | ||||
| +   549   while (!atomic_compare_exchange_weak_release
 | ||||
| +   550          (&rwlock->__data.__readers, &r,
 | ||||
| +   551           ((r ^ PTHREAD_RWLOCK_WRLOCKED)
 | ||||
| +   552            ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
 | ||||
| +   553               : PTHREAD_RWLOCK_WRPHASE))))
 | ||||
| +   554     {
 | ||||
| +   ...
 | ||||
| +   556     }
 | ||||
| +
 | ||||
| +   We clear PTHREAD_RWLOCK_WRLOCKED, and if there are
 | ||||
| +   no readers so we leave the lock in PTHRAD_RWLOCK_WRPHASE.
 | ||||
| +
 | ||||
| +   Back in the read lock.
 | ||||
| +
 | ||||
| +   The read lock adjusts __readres as above.
 | ||||
| +
 | ||||
| +   383   while ((r & PTHREAD_RWLOCK_WRPHASE) != 0
 | ||||
| +   384          && (r & PTHREAD_RWLOCK_WRLOCKED) == 0)
 | ||||
| +   385     {
 | ||||
| +   ...
 | ||||
| +   390       if (atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers, &r,
 | ||||
| +   391                                                 r ^ PTHREAD_RWLOCK_WRPHASE))
 | ||||
| +   392         {
 | ||||
| +
 | ||||
| +   And then attemps to start the read phase.
 | ||||
| +
 | ||||
| +   Assume there happens to be a tryrdlock at this point, noting
 | ||||
| +   that PTHREAD_RWLOCK_WRLOCKED is clear, and PTHREAD_RWLOCK_WRPHASE
 | ||||
| +   is 1. So the try lock attemps to start the read phase.
 | ||||
| +
 | ||||
| +   In __pthread_rwlock_tryrdlock:
 | ||||
| +
 | ||||
| +    44       if ((r & PTHREAD_RWLOCK_WRPHASE) == 0)
 | ||||
| +    45         {
 | ||||
| +   ...
 | ||||
| +    49           if (((r & PTHREAD_RWLOCK_WRLOCKED) != 0)
 | ||||
| +    50               && (rwlock->__data.__flags
 | ||||
| +    51                   == PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP))
 | ||||
| +    52             return EBUSY;
 | ||||
| +    53           rnew = r + (1 << PTHREAD_RWLOCK_READER_SHIFT);
 | ||||
| +    54         }
 | ||||
| +   ...
 | ||||
| +    89   while (!atomic_compare_exchange_weak_acquire (&rwlock->__data.__readers,
 | ||||
| +    90       &r, rnew));
 | ||||
| +
 | ||||
| +   And succeeds.
 | ||||
| +
 | ||||
| +   Back in the write unlock:
 | ||||
| +
 | ||||
| +   557   if ((r >> PTHREAD_RWLOCK_READER_SHIFT) != 0)
 | ||||
| +   558     {
 | ||||
| +   ...
 | ||||
| +   563       if ((atomic_exchange_relaxed (&rwlock->__data.__wrphase_futex, 0)
 | ||||
| +   564            & PTHREAD_RWLOCK_FUTEX_USED) != 0)
 | ||||
| +   565         futex_wake (&rwlock->__data.__wrphase_futex, INT_MAX, private);
 | ||||
| +   566     }
 | ||||
| +
 | ||||
| +   We note that PTHREAD_RWLOCK_FUTEX_USED is non-zero
 | ||||
| +   and don't wake anyone. This is OK because we handed
 | ||||
| +   over to the trylock. It will be the trylock's responsibility
 | ||||
| +   to wake any waiters.
 | ||||
| +
 | ||||
| +   Back in the read lock:
 | ||||
| +
 | ||||
| +   The read lock fails to install PTHRAD_REWLOCK_WRPHASE as 0 because
 | ||||
| +   the __readers value was adjusted by the trylock, and so it falls through
 | ||||
| +   to waiting on the lock for explicit handover from either a new writer
 | ||||
| +   or a new reader.
 | ||||
| +
 | ||||
| +   448           int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
 | ||||
| +   449                                          1 | PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +   450                                          abstime, private);
 | ||||
| +
 | ||||
| +   We use PTHREAD_RWLOCK_FUTEX_USED to indicate the futex
 | ||||
| +   is in use.
 | ||||
| +
 | ||||
| +   At this point we have readers waiting on the read lock
 | ||||
| +   to unlock. The wrlock is done. The trylock is finishing
 | ||||
| +   the installation of the read phase.
 | ||||
| +
 | ||||
| +    92   if ((r & PTHREAD_RWLOCK_WRPHASE) != 0)
 | ||||
| +    93     {
 | ||||
| +   ...
 | ||||
| +   105       atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 0);
 | ||||
| +   106     }
 | ||||
| +
 | ||||
| +   The trylock does note that we were the one that
 | ||||
| +   installed the read phase, but the comments are not
 | ||||
| +   correct, the execution ordering above shows that
 | ||||
| +   readers might indeed be waiting, and they are.
 | ||||
| +
 | ||||
| +   The atomic_store_relaxed throws away PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +   and the waiting reader is never worken becuase as noted
 | ||||
| +   above it is conditional on the futex being used.
 | ||||
| +
 | ||||
| +   The solution is for the trylock thread to inspect
 | ||||
| +   PTHREAD_RWLOCK_FUTEX_USED and wake the waiting readers.
 | ||||
| +
 | ||||
| +   --- Analysis of pthread_rwlock_trywrlock() stall ---
 | ||||
| +
 | ||||
| +   A write lock begins to execute, takes the write lock,
 | ||||
| +   and then releases the lock...
 | ||||
| +
 | ||||
| +   In pthread_rwlock_wrunlock():
 | ||||
| +
 | ||||
| +   547   unsigned int r = atomic_load_relaxed (&rwlock->__data.__readers);
 | ||||
| +   ...
 | ||||
| +   549   while (!atomic_compare_exchange_weak_release
 | ||||
| +   550          (&rwlock->__data.__readers, &r,
 | ||||
| +   551           ((r ^ PTHREAD_RWLOCK_WRLOCKED)
 | ||||
| +   552            ^ ((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0 ? 0
 | ||||
| +   553               : PTHREAD_RWLOCK_WRPHASE))))
 | ||||
| +   554     {
 | ||||
| +   ...
 | ||||
| +   556     }
 | ||||
| +
 | ||||
| +   ... leaving it in the write phase with zero readers
 | ||||
| +   (the case where we leave the write phase in place
 | ||||
| +   during a write unlock).
 | ||||
| +
 | ||||
| +   A write trylock begins to execute.
 | ||||
| +
 | ||||
| +   In __pthread_rwlock_trywrlock:
 | ||||
| +
 | ||||
| +    40   while (((r & PTHREAD_RWLOCK_WRLOCKED) == 0)
 | ||||
| +    41       && (((r >> PTHREAD_RWLOCK_READER_SHIFT) == 0)
 | ||||
| +    42           || (prefer_writer && ((r & PTHREAD_RWLOCK_WRPHASE) != 0))))
 | ||||
| +    43     {
 | ||||
| +
 | ||||
| +   The lock is not locked.
 | ||||
| +
 | ||||
| +   There are no readers.
 | ||||
| +
 | ||||
| +    45       if (atomic_compare_exchange_weak_acquire (
 | ||||
| +    46           &rwlock->__data.__readers, &r,
 | ||||
| +    47           r | PTHREAD_RWLOCK_WRPHASE | PTHREAD_RWLOCK_WRLOCKED))
 | ||||
| +
 | ||||
| +   We atomically install the write phase and we take the
 | ||||
| +   exclusive write lock.
 | ||||
| +
 | ||||
| +    48         {
 | ||||
| +    49           atomic_store_relaxed (&rwlock->__data.__writers_futex, 1);
 | ||||
| +
 | ||||
| +   We get this far.
 | ||||
| +
 | ||||
| +   A reader lock begins to execute.
 | ||||
| +
 | ||||
| +   In pthread_rwlock_rdlock:
 | ||||
| +
 | ||||
| +   437   for (;;)
 | ||||
| +   438     {
 | ||||
| +   439       while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
 | ||||
| +   440               | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
| +   441         {
 | ||||
| +   442           int private = __pthread_rwlock_get_private (rwlock);
 | ||||
| +   443           if (((wpf & PTHREAD_RWLOCK_FUTEX_USED) == 0)
 | ||||
| +   444               && (!atomic_compare_exchange_weak_relaxed
 | ||||
| +   445                   (&rwlock->__data.__wrphase_futex,
 | ||||
| +   446                    &wpf, wpf | PTHREAD_RWLOCK_FUTEX_USED)))
 | ||||
| +   447             continue;
 | ||||
| +   448           int err = futex_abstimed_wait (&rwlock->__data.__wrphase_futex,
 | ||||
| +   449                                          1 | PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +   450                                          abstime, private);
 | ||||
| +
 | ||||
| +   We are in a write phase, so the while() on line 439 is true.
 | ||||
| +
 | ||||
| +   The value of wpf does not have PTHREAD_RWLOCK_FUTEX_USED set
 | ||||
| +   since this is the first reader to lock.
 | ||||
| +
 | ||||
| +   The atomic operation sets wpf with PTHREAD_RELOCK_FUTEX_USED
 | ||||
| +   on the expectation that this reader will be woken during
 | ||||
| +   the handoff.
 | ||||
| +
 | ||||
| +   Back in pthread_rwlock_trywrlock:
 | ||||
| +
 | ||||
| +    50           atomic_store_relaxed (&rwlock->__data.__wrphase_futex, 1);
 | ||||
| +    51           atomic_store_relaxed (&rwlock->__data.__cur_writer,
 | ||||
| +    52               THREAD_GETMEM (THREAD_SELF, tid));
 | ||||
| +    53           return 0;
 | ||||
| +    54         }
 | ||||
| +   ...
 | ||||
| +    57     }
 | ||||
| +
 | ||||
| +   We write 1 to __wrphase_futex discarding PTHREAD_RWLOCK_FUTEX_USED,
 | ||||
| +   and so in the unlock we will not awaken the waiting reader.
 | ||||
| +
 | ||||
| +   The solution to this is to realize that if we did not start the write
 | ||||
| +   phase we need not write 1 or any other value to __wrphase_futex.
 | ||||
| +   This ensures that any readers (which saw __wrphase_futex != 0) can
 | ||||
| +   set PTHREAD_RWLOCK_FUTEX_USED and this can be used at unlock to
 | ||||
| +   wake them.
 | ||||
| +
 | ||||
| +   If we installed the write phase then all other readers are looping
 | ||||
| +   here:
 | ||||
| +
 | ||||
| +   In __pthread_rwlock_rdlock_full:
 | ||||
| +
 | ||||
| +   437   for (;;)
 | ||||
| +   438     {
 | ||||
| +   439       while (((wpf = atomic_load_relaxed (&rwlock->__data.__wrphase_futex))
 | ||||
| +   440               | PTHREAD_RWLOCK_FUTEX_USED) == (1 | PTHREAD_RWLOCK_FUTEX_USED))
 | ||||
| +   441         {
 | ||||
| +   ...
 | ||||
| +   508     }
 | ||||
| +
 | ||||
| +   waiting for the write phase to be installed or removed before they
 | ||||
| +   can begin waiting on __wrphase_futex (part of the algorithm), or
 | ||||
| +   taking a concurrent read lock, and thus we can safely write 1 to
 | ||||
| +   __wrphase_futex.
 | ||||
| +
 | ||||
| +   If we did not install the write phase then the readers may already
 | ||||
| +   be waiting on the futex, the original writer wrote 1 to __wrphase_futex
 | ||||
| +   as part of starting the write phase, and we cannot also write 1
 | ||||
| +   without loosing the PTHREAD_RWLOCK_FUTEX_USED bit.
 | ||||
| +
 | ||||
| +   ---
 | ||||
| +
 | ||||
| +   Summary for the pthread_rwlock_tryrdlock() stall:
 | ||||
| +
 | ||||
| +   The stall is caused by pthread_rwlock_tryrdlock failing to check
 | ||||
| +   that PTHREAD_RWLOCK_FUTEX_USED is set in the __wrphase_futex futex
 | ||||
| +   and then waking the futex.
 | ||||
| +
 | ||||
| +   The fix for bug 23844 ensures that waiters on __wrphase_futex are
 | ||||
| +   correctly woken.  Before the fix the test stalls as readers can
 | ||||
| +   wait forever on __wrphase_futex.  */
 | ||||
| +
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#include <pthread.h>
 | ||||
| +#include <support/xthread.h>
 | ||||
| +#include <errno.h>
 | ||||
| +
 | ||||
| +/* We need only one lock to reproduce the issue. We will need multiple
 | ||||
| +   threads to get the exact case where we have a read, try, and unlock
 | ||||
| +   all interleaving to produce the case where the readers are waiting
 | ||||
| +   and the try fails to wake them.  */
 | ||||
| +pthread_rwlock_t onelock;
 | ||||
| +
 | ||||
| +/* The number of threads is arbitrary but empirically chosen to have
 | ||||
| +   enough threads that we see the condition where waiting readers are
 | ||||
| +   not woken by a successful tryrdlock.  */
 | ||||
| +#define NTHREADS 32
 | ||||
| +
 | ||||
| +_Atomic int do_exit;
 | ||||
| +
 | ||||
| +void *
 | ||||
| +run_loop (void *arg)
 | ||||
| +{
 | ||||
| +  int i = 0, ret;
 | ||||
| +  while (!do_exit)
 | ||||
| +    {
 | ||||
| +      /* Arbitrarily choose if we are the writer or reader.  Choose a
 | ||||
| +	 high enough ratio of readers to writers to make it likely
 | ||||
| +	 that readers block (and eventually are susceptable to
 | ||||
| +	 stalling).
 | ||||
| +
 | ||||
| +         If we are a writer, take the write lock, and then unlock.
 | ||||
| +	 If we are a reader, try the lock, then lock, then unlock.  */
 | ||||
| +      if ((i % 8) != 0)
 | ||||
| +	xpthread_rwlock_wrlock (&onelock);
 | ||||
| +      else
 | ||||
| +	{
 | ||||
| +	  if ((ret = pthread_rwlock_tryrdlock (&onelock)) != 0)
 | ||||
| +	    {
 | ||||
| +	      if (ret == EBUSY)
 | ||||
| +		xpthread_rwlock_rdlock (&onelock);
 | ||||
| +	      else
 | ||||
| +		exit (EXIT_FAILURE);
 | ||||
| +	    }
 | ||||
| +	}
 | ||||
| +      /* Thread does some work and then unlocks.  */
 | ||||
| +      xpthread_rwlock_unlock (&onelock);
 | ||||
| +      i++;
 | ||||
| +    }
 | ||||
| +  return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  int i;
 | ||||
| +  pthread_t tids[NTHREADS];
 | ||||
| +  xpthread_rwlock_init (&onelock, NULL);
 | ||||
| +  for (i = 0; i < NTHREADS; i++)
 | ||||
| +    tids[i] = xpthread_create (NULL, run_loop, NULL);
 | ||||
| +  /* Run for some amount of time.  Empirically speaking exercising
 | ||||
| +     the stall via pthread_rwlock_tryrdlock is much harder, and on
 | ||||
| +     a 3.5GHz 4 core x86_64 VM system it takes somewhere around
 | ||||
| +     20-200s to stall, approaching 100% stall past 200s.  We can't
 | ||||
| +     wait that long for a regression test so we just test for 20s,
 | ||||
| +     and expect the stall to happen with a 5-10% chance (enough for
 | ||||
| +     developers to see).  */
 | ||||
| +  sleep (20);
 | ||||
| +  /* Then exit.  */
 | ||||
| +  printf ("INFO: Exiting...\n");
 | ||||
| +  do_exit = 1;
 | ||||
| +  /* If any readers stalled then we will timeout waiting for them.  */
 | ||||
| +  for (i = 0; i < NTHREADS; i++)
 | ||||
| +    xpthread_join (tids[i]);
 | ||||
| +  printf ("INFO: Done.\n");
 | ||||
| +  xpthread_rwlock_destroy (&onelock);
 | ||||
| +  printf ("PASS: No pthread_rwlock_tryrdlock stalls detected.\n");
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#define TIMEOUT 30
 | ||||
| +#include <support/test-driver.c>
 | ||||
| diff --git a/nptl/tst-rwlock-trywrlock-stall.c b/nptl/tst-rwlock-trywrlock-stall.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..14d27cbcbc882cb1
 | ||||
| --- /dev/null
 | ||||
| +++ b/nptl/tst-rwlock-trywrlock-stall.c
 | ||||
| @@ -0,0 +1,108 @@
 | ||||
| +/* Bug 23844: Test for pthread_rwlock_trywrlock stalls.
 | ||||
| +   Copyright (C) 2019 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +/* For a full analysis see comments in tst-rwlock-tryrdlock-stall.c.
 | ||||
| +
 | ||||
| +   Summary for the pthread_rwlock_trywrlock() stall:
 | ||||
| +
 | ||||
| +   The stall is caused by pthread_rwlock_trywrlock setting
 | ||||
| +   __wrphase_futex futex to 1 and loosing the
 | ||||
| +   PTHREAD_RWLOCK_FUTEX_USED bit.
 | ||||
| +
 | ||||
| +   The fix for bug 23844 ensures that waiters on __wrphase_futex are
 | ||||
| +   correctly woken.  Before the fix the test stalls as readers can
 | ||||
| +   wait forever on  __wrphase_futex.  */
 | ||||
| +
 | ||||
| +#include <stdio.h>
 | ||||
| +#include <stdlib.h>
 | ||||
| +#include <unistd.h>
 | ||||
| +#include <pthread.h>
 | ||||
| +#include <support/xthread.h>
 | ||||
| +#include <errno.h>
 | ||||
| +
 | ||||
| +/* We need only one lock to reproduce the issue. We will need multiple
 | ||||
| +   threads to get the exact case where we have a read, try, and unlock
 | ||||
| +   all interleaving to produce the case where the readers are waiting
 | ||||
| +   and the try clears the PTHREAD_RWLOCK_FUTEX_USED bit and a
 | ||||
| +   subsequent unlock fails to wake them.  */
 | ||||
| +pthread_rwlock_t onelock;
 | ||||
| +
 | ||||
| +/* The number of threads is arbitrary but empirically chosen to have
 | ||||
| +   enough threads that we see the condition where waiting readers are
 | ||||
| +   not woken by a successful unlock.  */
 | ||||
| +#define NTHREADS 32
 | ||||
| +
 | ||||
| +_Atomic int do_exit;
 | ||||
| +
 | ||||
| +void *
 | ||||
| +run_loop (void *arg)
 | ||||
| +{
 | ||||
| +  int i = 0, ret;
 | ||||
| +  while (!do_exit)
 | ||||
| +    {
 | ||||
| +      /* Arbitrarily choose if we are the writer or reader.  Choose a
 | ||||
| +	 high enough ratio of readers to writers to make it likely
 | ||||
| +	 that readers block (and eventually are susceptable to
 | ||||
| +	 stalling).
 | ||||
| +
 | ||||
| +         If we are a writer, take the write lock, and then unlock.
 | ||||
| +	 If we are a reader, try the lock, then lock, then unlock.  */
 | ||||
| +      if ((i % 8) != 0)
 | ||||
| +	{
 | ||||
| +	  if ((ret = pthread_rwlock_trywrlock (&onelock)) != 0)
 | ||||
| +	    {
 | ||||
| +	      if (ret == EBUSY)
 | ||||
| +		xpthread_rwlock_wrlock (&onelock);
 | ||||
| +	      else
 | ||||
| +		exit (EXIT_FAILURE);
 | ||||
| +	    }
 | ||||
| +	}
 | ||||
| +      else
 | ||||
| +	xpthread_rwlock_rdlock (&onelock);
 | ||||
| +      /* Thread does some work and then unlocks.  */
 | ||||
| +      xpthread_rwlock_unlock (&onelock);
 | ||||
| +      i++;
 | ||||
| +    }
 | ||||
| +  return NULL;
 | ||||
| +}
 | ||||
| +
 | ||||
| +int
 | ||||
| +do_test (void)
 | ||||
| +{
 | ||||
| +  int i;
 | ||||
| +  pthread_t tids[NTHREADS];
 | ||||
| +  xpthread_rwlock_init (&onelock, NULL);
 | ||||
| +  for (i = 0; i < NTHREADS; i++)
 | ||||
| +    tids[i] = xpthread_create (NULL, run_loop, NULL);
 | ||||
| +  /* Run for some amount of time.  The pthread_rwlock_tryrwlock stall
 | ||||
| +     is very easy to trigger and happens in seconds under the test
 | ||||
| +     conditions.  */
 | ||||
| +  sleep (10);
 | ||||
| +  /* Then exit.  */
 | ||||
| +  printf ("INFO: Exiting...\n");
 | ||||
| +  do_exit = 1;
 | ||||
| +  /* If any readers stalled then we will timeout waiting for them.  */
 | ||||
| +  for (i = 0; i < NTHREADS; i++)
 | ||||
| +    xpthread_join (tids[i]);
 | ||||
| +  printf ("INFO: Done.\n");
 | ||||
| +  xpthread_rwlock_destroy (&onelock);
 | ||||
| +  printf ("PASS: No pthread_rwlock_tryrwlock stalls detected.\n");
 | ||||
| +  return 0;
 | ||||
| +}
 | ||||
| +
 | ||||
| +#include <support/test-driver.c>
 | ||||
| diff --git a/support/Makefile b/support/Makefile
 | ||||
| index 93a514301654132e..41da4abaaa5a645a 100644
 | ||||
| --- a/support/Makefile
 | ||||
| +++ b/support/Makefile
 | ||||
| @@ -129,6 +129,7 @@ libsupport-routines = \
 | ||||
|    xpthread_mutexattr_settype \ | ||||
|    xpthread_once \ | ||||
|    xpthread_rwlock_init \ | ||||
| +  xpthread_rwlock_destroy \
 | ||||
|    xpthread_rwlock_rdlock \ | ||||
|    xpthread_rwlock_unlock \ | ||||
|    xpthread_rwlock_wrlock \ | ||||
| diff --git a/support/xpthread_rwlock_destroy.c b/support/xpthread_rwlock_destroy.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..6d6e95356963b47f
 | ||||
| --- /dev/null
 | ||||
| +++ b/support/xpthread_rwlock_destroy.c
 | ||||
| @@ -0,0 +1,26 @@
 | ||||
| +/* pthread_rwlock_destroy with error checking.
 | ||||
| +   Copyright (C) 2019 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <support/xthread.h>
 | ||||
| +
 | ||||
| +void
 | ||||
| +xpthread_rwlock_destroy (pthread_rwlock_t *rwlock)
 | ||||
| +{
 | ||||
| +  xpthread_check_return ("pthread_rwlock_destroy",
 | ||||
| +                         pthread_rwlock_destroy (rwlock));
 | ||||
| +}
 | ||||
| diff --git a/support/xthread.h b/support/xthread.h
 | ||||
| index 623f5ad0acb895ef..1af77280871464c2 100644
 | ||||
| --- a/support/xthread.h
 | ||||
| +++ b/support/xthread.h
 | ||||
| @@ -84,6 +84,7 @@ void xpthread_rwlockattr_setkind_np (pthread_rwlockattr_t *attr, int pref);
 | ||||
|  void xpthread_rwlock_wrlock (pthread_rwlock_t *rwlock); | ||||
|  void xpthread_rwlock_rdlock (pthread_rwlock_t *rwlock); | ||||
|  void xpthread_rwlock_unlock (pthread_rwlock_t *rwlock); | ||||
| +void xpthread_rwlock_destroy (pthread_rwlock_t *rwlock);
 | ||||
|   | ||||
|  __END_DECLS | ||||
|   | ||||
							
								
								
									
										61
									
								
								SOURCES/glibc-rh1659293-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								SOURCES/glibc-rh1659293-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,61 @@ | ||||
| nptl/tst-rwlock14: Test pthread_rwlock_timedwrlock correctly | ||||
| 
 | ||||
| (cherry picked from commit 82849fde3b8cb9b9396fa8cadf842dc2b1d2cced) | ||||
| 
 | ||||
| diff --git a/ChangeLog b/ChangeLog
 | ||||
| index ed1a2ffe8356fd96..74e634670c62d5c2 100644
 | ||||
| --- a/ChangeLog
 | ||||
| +++ b/ChangeLog
 | ||||
| @@ -1,3 +1,10 @@
 | ||||
| +2019-03-25  Mike Crowe  <mac@mcrowe.com>
 | ||||
| +
 | ||||
| +	* nptl/tst-rwlock14.c (do_test): Replace duplicate calls to
 | ||||
| +	pthread_rwlock_timedrdlock with calls to
 | ||||
| +	pthread_rwlock_timedwrlock to ensure that the latter is tested
 | ||||
| +	too. Use new function name in diagnostic messages too.
 | ||||
| +
 | ||||
|  2019-01-31  Carlos O'Donell  <carlos@redhat.com> | ||||
|  	    Torvald Riegel  <triegel@redhat.com> | ||||
|  	    Rik Prohaska  <prohaska7@gmail.com> | ||||
| diff --git a/nptl/tst-rwlock14.c b/nptl/tst-rwlock14.c
 | ||||
| index d6fda87c61e9aed4..073e6c98d2f5cc12 100644
 | ||||
| --- a/nptl/tst-rwlock14.c
 | ||||
| +++ b/nptl/tst-rwlock14.c
 | ||||
| @@ -117,15 +117,15 @@ do_test (void)
 | ||||
|        result = 1; | ||||
|      } | ||||
|   | ||||
| -  e = pthread_rwlock_timedrdlock (&r, &ts);
 | ||||
| +  e = pthread_rwlock_timedwrlock (&r, &ts);
 | ||||
|    if (e == 0) | ||||
|      { | ||||
| -      puts ("second rwlock_timedrdlock did not fail");
 | ||||
| +      puts ("second rwlock_timedwrlock did not fail");
 | ||||
|        result = 1; | ||||
|      } | ||||
|    else if (e != EINVAL) | ||||
|      { | ||||
| -      puts ("second rwlock_timedrdlock did not return EINVAL");
 | ||||
| +      puts ("second rwlock_timedwrlock did not return EINVAL");
 | ||||
|        result = 1; | ||||
|      } | ||||
|   | ||||
| @@ -145,15 +145,15 @@ do_test (void)
 | ||||
|        result = 1; | ||||
|      } | ||||
|   | ||||
| -  e = pthread_rwlock_timedrdlock (&r, &ts);
 | ||||
| +  e = pthread_rwlock_timedwrlock (&r, &ts);
 | ||||
|    if (e == 0) | ||||
|      { | ||||
| -      puts ("third rwlock_timedrdlock did not fail");
 | ||||
| +      puts ("third rwlock_timedwrlock did not fail");
 | ||||
|        result = 1; | ||||
|      } | ||||
|    else if (e != EINVAL) | ||||
|      { | ||||
| -      puts ("third rwlock_timedrdlock did not return EINVAL");
 | ||||
| +      puts ("third rwlock_timedwrlock did not return EINVAL");
 | ||||
|        result = 1; | ||||
|      } | ||||
|   | ||||
							
								
								
									
										118
									
								
								SOURCES/glibc-rh1659438-1.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								SOURCES/glibc-rh1659438-1.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,118 @@ | ||||
| commit b8686c0d7098168481a246f8199ab2d865f52d3d | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:03 2018 +0100 | ||||
| 
 | ||||
|     S390: Add configure check to detect z10 as mininum architecture level set. | ||||
|      | ||||
|     Add a configure check for z10 in the same way as done for z196. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * config.h.in (HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT): New undefine. | ||||
|             * sysdeps/s390/configure.ac: Add check for z10 support. | ||||
|             * sysdeps/s390/configure: Regenerated. | ||||
| 
 | ||||
| diff --git a/config.h.in b/config.h.in
 | ||||
| index 141db213a9046eb4..beecc39d5b8c3f4a 100644
 | ||||
| --- a/config.h.in
 | ||||
| +++ b/config.h.in
 | ||||
| @@ -62,6 +62,9 @@
 | ||||
|  /* Define if assembler supports AVX512DQ.  */ | ||||
|  #undef  HAVE_AVX512DQ_ASM_SUPPORT | ||||
|   | ||||
| +/* Define if assembler supports z10 zarch instructions as default on S390.  */
 | ||||
| +#undef  HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
 | ||||
| +
 | ||||
|  /* Define if assembler supports z196 zarch instructions as default on S390.  */ | ||||
|  #undef  HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT | ||||
|   | ||||
| diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
 | ||||
| index 74b415f2ab0fa982..f30f8644361f474a 100644
 | ||||
| --- a/sysdeps/s390/configure
 | ||||
| +++ b/sysdeps/s390/configure
 | ||||
| @@ -112,6 +112,45 @@ then
 | ||||
|   | ||||
|  fi | ||||
|   | ||||
| +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z10 zarch instruction support as default" >&5
 | ||||
| +$as_echo_n "checking for S390 z10 zarch instruction support as default... " >&6; }
 | ||||
| +if ${libc_cv_asm_s390_min_z10_zarch+:} false; then :
 | ||||
| +  $as_echo_n "(cached) " >&6
 | ||||
| +else
 | ||||
| +  cat > conftest.c <<\EOF
 | ||||
| +void testinsn (void *a, void *b, int n)
 | ||||
| +{
 | ||||
| +    __asm__ ("exrl %2,1f \n\t"
 | ||||
| +	     "j 2f \n\t"
 | ||||
| +	     "1: mvc 0(1,%0),0(%1) \n\t"
 | ||||
| +	     "2:"
 | ||||
| +	     : : "a" (a), "a" (b), "d" (n)
 | ||||
| +	     : "memory", "cc");
 | ||||
| +}
 | ||||
| +EOF
 | ||||
| +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
 | ||||
| +			-o conftest.o &> /dev/null'
 | ||||
| +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
 | ||||
| +  (eval $ac_try) 2>&5
 | ||||
| +  ac_status=$?
 | ||||
| +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
 | ||||
| +  test $ac_status = 0; }; } ;
 | ||||
| +then
 | ||||
| +  libc_cv_asm_s390_min_z10_zarch=yes
 | ||||
| +else
 | ||||
| +  libc_cv_asm_s390_min_z10_zarch=no
 | ||||
| +fi
 | ||||
| +rm -f conftest*
 | ||||
| +fi
 | ||||
| +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z10_zarch" >&5
 | ||||
| +$as_echo "$libc_cv_asm_s390_min_z10_zarch" >&6; }
 | ||||
| +
 | ||||
| +if test "$libc_cv_asm_s390_min_z10_zarch" = yes ;
 | ||||
| +then
 | ||||
| +  $as_echo "#define HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT 1" >>confdefs.h
 | ||||
| +
 | ||||
| +fi
 | ||||
| +
 | ||||
|  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z196 zarch instruction support as default" >&5 | ||||
|  $as_echo_n "checking for S390 z196 zarch instruction support as default... " >&6; } | ||||
|  if ${libc_cv_asm_s390_min_z196_zarch+:} false; then : | ||||
| diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
 | ||||
| index 1cdb0212825a3f18..981f7a79dd7066fc 100644
 | ||||
| --- a/sysdeps/s390/configure.ac
 | ||||
| +++ b/sysdeps/s390/configure.ac
 | ||||
| @@ -80,6 +80,35 @@ then
 | ||||
|    AC_DEFINE(HAVE_S390_VX_GCC_SUPPORT) | ||||
|  fi | ||||
|   | ||||
| +AC_CACHE_CHECK(for S390 z10 zarch instruction support as default,
 | ||||
| +	       libc_cv_asm_s390_min_z10_zarch, [dnl
 | ||||
| +cat > conftest.c <<\EOF
 | ||||
| +void testinsn (void *a, void *b, int n)
 | ||||
| +{
 | ||||
| +    __asm__ ("exrl %2,1f \n\t"
 | ||||
| +	     "j 2f \n\t"
 | ||||
| +	     "1: mvc 0(1,%0),0(%1) \n\t"
 | ||||
| +	     "2:"
 | ||||
| +	     : : "a" (a), "a" (b), "d" (n)
 | ||||
| +	     : "memory", "cc");
 | ||||
| +}
 | ||||
| +EOF
 | ||||
| +dnl
 | ||||
| +dnl test, if assembler supports S390 z10 zarch instructions as default
 | ||||
| +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
 | ||||
| +			-o conftest.o &> /dev/null]) ;
 | ||||
| +then
 | ||||
| +  libc_cv_asm_s390_min_z10_zarch=yes
 | ||||
| +else
 | ||||
| +  libc_cv_asm_s390_min_z10_zarch=no
 | ||||
| +fi
 | ||||
| +rm -f conftest* ])
 | ||||
| +
 | ||||
| +if test "$libc_cv_asm_s390_min_z10_zarch" = yes ;
 | ||||
| +then
 | ||||
| +  AC_DEFINE(HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT)
 | ||||
| +fi
 | ||||
| +
 | ||||
|  AC_CACHE_CHECK(for S390 z196 zarch instruction support as default, | ||||
|  	       libc_cv_asm_s390_min_z196_zarch, [dnl | ||||
|  cat > conftest.c <<\EOF | ||||
							
								
								
									
										189
									
								
								SOURCES/glibc-rh1659438-10.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								SOURCES/glibc-rh1659438-10.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,189 @@ | ||||
| commit e099aab060df178a7fcd5a55282650fe45ccea66 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:07 2018 +0100 | ||||
| 
 | ||||
|     S390: Remove s390 specific implementation of bcopy. | ||||
|      | ||||
|     Nowadays gcc is automatically replacing a call to bcopy | ||||
|     with a call to memmove.  Thus only old binaries will call | ||||
|     the s390 specific bcopy implementation. | ||||
|      | ||||
|     The s390 specific implementation is using an own | ||||
|     implementation for memcpy in the forward case and is | ||||
|     relying on memmove in the backward case. | ||||
|      | ||||
|     After removing the s390 specific bcopy, the common code | ||||
|     bcopy is used.  It just performs a tail call to memmove. | ||||
|      | ||||
|     ChangeLog: | ||||
|             * sysdeps/s390/s390-32/bcopy.S: Remove. | ||||
|             * sysdeps/s390/s390-64/bcopy.S: Likewise. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/s390-32/bcopy.S b/sysdeps/s390/s390-32/bcopy.S
 | ||||
| deleted file mode 100644 | ||||
| index 560e04fdee93dafb..0000000000000000
 | ||||
| --- a/sysdeps/s390/s390-32/bcopy.S
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,85 +0,0 @@
 | ||||
| -/* bcopy -- copy a block from source to destination.  S/390 version.
 | ||||
| -   This file is part of the GNU C Library.
 | ||||
| -   Copyright (C) 2000-2018 Free Software Foundation, Inc.
 | ||||
| -   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -/* INPUT PARAMETERS
 | ||||
| -     %r2 = address of source
 | ||||
| -     %r3 = address of destination
 | ||||
| -     %r4 = number of bytes to copy.  */
 | ||||
| -
 | ||||
| -#include "sysdep.h"
 | ||||
| -#include "asm-syntax.h"
 | ||||
| -
 | ||||
| -        .text
 | ||||
| -ENTRY(__bcopy)
 | ||||
| -	ltr     %r1,%r4             # zero bcopy ?
 | ||||
| -	jz      .L4
 | ||||
| -        clr     %r2,%r3             # check against destructive overlap
 | ||||
| -        jnl     .L0
 | ||||
| -        alr     %r1,%r2
 | ||||
| -        clr     %r1,%r3
 | ||||
| -        jh      .L7
 | ||||
| -.L0:	ahi     %r4,-1              # length - 1
 | ||||
| -	lr      %r1,%r4
 | ||||
| -	srl     %r1,8
 | ||||
| -	ltr     %r1,%r1             # < 256 bytes to move ?
 | ||||
| -	jz      .L2
 | ||||
| -	chi     %r1,255             # > 1MB to move ?
 | ||||
| -	jh      .L5
 | ||||
| -.L1:	mvc     0(256,%r3),0(%r2)   # move in 256 byte chunks
 | ||||
| -	la      %r2,256(%r2)
 | ||||
| -	la      %r3,256(%r3)
 | ||||
| -	brct    %r1,.L1
 | ||||
| -.L2:	bras    %r1,.L3             # setup base pointer for execute
 | ||||
| -	mvc     0(1,%r3),0(%r2)     # instruction for execute
 | ||||
| -.L3:	ex      %r4,0(%r1)          # execute mvc with length ((%r4)&255)+1
 | ||||
| -.L4:	br      %r14
 | ||||
| -
 | ||||
| -	# data copies > 1MB are faster with mvcle.
 | ||||
| -.L5:	ahi     %r4,1               # length + 1
 | ||||
| -	lr      %r5,%r4	            # source length
 | ||||
| -	lr	%r4,%r2             # source address
 | ||||
| -	lr	%r2,%r3             # set destination
 | ||||
| -	lr	%r3,%r5             # destination length = source length
 | ||||
| -.L6:	mvcle	%r2,%r4,0           # thats it, MVCLE is your friend
 | ||||
| -	jo	.L6
 | ||||
| -	br	%r14
 | ||||
| -.L7:                                # destructive overlay, can not use mvcle
 | ||||
| -        lr     %r1,%r2              # bcopy is called with source,dest
 | ||||
| -        lr     %r2,%r3              # memmove with dest,source! Oh, well...
 | ||||
| -        lr     %r3,%r1
 | ||||
| -        basr   %r1,0
 | ||||
| -.L8:
 | ||||
| -#ifdef PIC
 | ||||
| -        al     %r1,.L9-.L8(%r1)     # get address of global offset table
 | ||||
| -                                    # load address of memmove
 | ||||
| -        l      %r1,memmove@GOT(%r1)
 | ||||
| -        br     %r1
 | ||||
| -.L9:    .long  _GLOBAL_OFFSET_TABLE_-.L8
 | ||||
| -#else
 | ||||
| -        al     %r1,.L9-.L8(%r1)     # load address of memmove
 | ||||
| -        br     %r1                  # jump to memmove
 | ||||
| -.L9:    .long  memmove-.L8
 | ||||
| -#endif
 | ||||
| -
 | ||||
| -END(__bcopy)
 | ||||
| -
 | ||||
| -#ifndef NO_WEAK_ALIAS
 | ||||
| -weak_alias (__bcopy, bcopy)
 | ||||
| -#endif
 | ||||
| -
 | ||||
| diff --git a/sysdeps/s390/s390-64/bcopy.S b/sysdeps/s390/s390-64/bcopy.S
 | ||||
| deleted file mode 100644 | ||||
| index 806dd15d0203d32a..0000000000000000
 | ||||
| --- a/sysdeps/s390/s390-64/bcopy.S
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,71 +0,0 @@
 | ||||
| -/* bcopy -- copy a block from source to destination.  64 bit S/390 version.
 | ||||
| -   This file is part of the GNU C Library.
 | ||||
| -   Copyright (C) 2000-2018 Free Software Foundation, Inc.
 | ||||
| -   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -/* INPUT PARAMETERS
 | ||||
| -     %r2 = address of source
 | ||||
| -     %r3 = address of destination
 | ||||
| -     %r4 = number of bytes to copy.  */
 | ||||
| -
 | ||||
| -#include "sysdep.h"
 | ||||
| -#include "asm-syntax.h"
 | ||||
| -
 | ||||
| -	.text
 | ||||
| -ENTRY(__bcopy)
 | ||||
| -	ltgr	%r1,%r4		    # zero bcopy ?
 | ||||
| -	jz	.L4
 | ||||
| -	clgr	%r2,%r3		    # check against destructive overlap
 | ||||
| -	jnl	.L0
 | ||||
| -	algr	%r1,%r2
 | ||||
| -	clgr	%r1,%r3
 | ||||
| -	jh	.L7
 | ||||
| -.L0:	aghi	%r4,-1		    # length - 1
 | ||||
| -	srlg	%r1,%r4,8
 | ||||
| -	ltgr	%r1,%r1             # < 256 bytes to move ?
 | ||||
| -	jz	.L2
 | ||||
| -	cghi    %r1,255             # > 1MB to move ?
 | ||||
| -	jh      .L5
 | ||||
| -.L1:	mvc	0(256,%r3),0(%r2)   # move in 256 byte chunks
 | ||||
| -	la	%r2,256(%r2)
 | ||||
| -	la	%r3,256(%r3)
 | ||||
| -	brctg	%r1,.L1
 | ||||
| -.L2:	bras	%r1,.L3		    # setup base pointer for execute
 | ||||
| -	mvc	0(1,%r3),0(%r2)	    # instruction for execute
 | ||||
| -.L3:	ex	%r4,0(%r1)	    # execute mvc with length ((%r4)&255)+1
 | ||||
| -.L4:	br	%r14
 | ||||
| -	# data copies > 1MB are faster with mvcle.
 | ||||
| -.L5:	aghi    %r4,1               # length + 1
 | ||||
| -	lgr	%r5,%r4	            # source length
 | ||||
| -	lgr	%r4,%r2             # source address
 | ||||
| -	lgr	%r2,%r3             # set destination
 | ||||
| -	lgr	%r3,%r5             # destination length = source length
 | ||||
| -.L6:	mvcle	%r2,%r4,0           # thats it, MVCLE is your friend
 | ||||
| -	jo	.L6
 | ||||
| -	br	%r14
 | ||||
| -.L7:				    # destructive overlay, can not use mvcle
 | ||||
| -	lgr	%r1,%r2		    # bcopy is called with source,dest
 | ||||
| -	lgr	%r2,%r3		    # memmove with dest,source! Oh, well...
 | ||||
| -	lgr	%r3,%r1
 | ||||
| -	jg	HIDDEN_BUILTIN_JUMPTARGET(memmove)
 | ||||
| -
 | ||||
| -END(__bcopy)
 | ||||
| -
 | ||||
| -#ifndef NO_WEAK_ALIAS
 | ||||
| -weak_alias (__bcopy, bcopy)
 | ||||
| -#endif
 | ||||
| -
 | ||||
							
								
								
									
										43
									
								
								SOURCES/glibc-rh1659438-11.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								SOURCES/glibc-rh1659438-11.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| commit d097d97626e44bc6e76d5daf80ce3ff7d147b623 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:07 2018 +0100 | ||||
| 
 | ||||
|     S390: Use memcpy for forward cases in memmove. | ||||
|      | ||||
|     The s390/s390x memcpy implementations are safe to be | ||||
|     used by memmove.  Starting with this commit, memmove is | ||||
|     using memcpy for the forward cases on s390. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/memcopy.h: New file. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/memcopy.h b/sysdeps/s390/memcopy.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..9a76196502f25bbf
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/memcopy.h
 | ||||
| @@ -0,0 +1,23 @@
 | ||||
| +/* memcopy.h -- definitions for memory copy functions.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <sysdeps/generic/memcopy.h>
 | ||||
| +
 | ||||
| +/* The s390/s390x memcpy implementations are safe to be used by memmove.  */
 | ||||
| +#undef MEMCPY_OK_FOR_FWD_MEMMOVE
 | ||||
| +#define MEMCPY_OK_FOR_FWD_MEMMOVE 1
 | ||||
							
								
								
									
										114
									
								
								SOURCES/glibc-rh1659438-12.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										114
									
								
								SOURCES/glibc-rh1659438-12.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,114 @@ | ||||
| commit 2ee1bc57ab50737ee2ab88c4d796b90e08b4bf93 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:08 2018 +0100 | ||||
| 
 | ||||
|     S390: Add configure check to detect z13 as mininum architecture level set. | ||||
|      | ||||
|     Add a configure check for z13 in the same way as done for z196. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * config.h.in (HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT): New undefine. | ||||
|             * sysdeps/s390/configure.ac: Add check for z13 support. | ||||
|             * sysdeps/s390/configure: Regenerated. | ||||
| 
 | ||||
| diff --git a/config.h.in b/config.h.in
 | ||||
| index beecc39d5b8c3f4a..422a6036ab16e3b6 100644
 | ||||
| --- a/config.h.in
 | ||||
| +++ b/config.h.in
 | ||||
| @@ -68,6 +68,9 @@
 | ||||
|  /* Define if assembler supports z196 zarch instructions as default on S390.  */ | ||||
|  #undef  HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT | ||||
|   | ||||
| +/* Define if assembler supports z13 zarch instructions as default on S390.  */
 | ||||
| +#undef  HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +
 | ||||
|  /* Define if assembler supports vector instructions on S390.  */ | ||||
|  #undef  HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
| diff --git a/sysdeps/s390/configure b/sysdeps/s390/configure
 | ||||
| index f30f8644361f474a..4a44775e3083d8c3 100644
 | ||||
| --- a/sysdeps/s390/configure
 | ||||
| +++ b/sysdeps/s390/configure
 | ||||
| @@ -187,5 +187,43 @@ then
 | ||||
|   | ||||
|  fi | ||||
|   | ||||
| +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for S390 z13 zarch instruction support as default" >&5
 | ||||
| +$as_echo_n "checking for S390 z13 zarch instruction support as default... " >&6; }
 | ||||
| +if ${libc_cv_asm_s390_min_z13_zarch+:} false; then :
 | ||||
| +  $as_echo_n "(cached) " >&6
 | ||||
| +else
 | ||||
| +  cat > conftest.c <<\EOF
 | ||||
| +int testinsn (void)
 | ||||
| +{
 | ||||
| +    int i;
 | ||||
| +    __asm__ ("vl %%v16,0(%%r15)\n\t"
 | ||||
| +	     "vlgvf %0,%%v16,0"
 | ||||
| +	     : "=d" (i) : : "memory", "v16");
 | ||||
| +    return i;
 | ||||
| +}
 | ||||
| +EOF
 | ||||
| +if { ac_try='${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
 | ||||
| +			-o conftest.o &> /dev/null'
 | ||||
| +  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
 | ||||
| +  (eval $ac_try) 2>&5
 | ||||
| +  ac_status=$?
 | ||||
| +  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
 | ||||
| +  test $ac_status = 0; }; } ;
 | ||||
| +then
 | ||||
| +  libc_cv_asm_s390_min_z13_zarch=yes
 | ||||
| +else
 | ||||
| +  libc_cv_asm_s390_min_z13_zarch=no
 | ||||
| +fi
 | ||||
| +rm -f conftest*
 | ||||
| +fi
 | ||||
| +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_asm_s390_min_z13_zarch" >&5
 | ||||
| +$as_echo "$libc_cv_asm_s390_min_z13_zarch" >&6; }
 | ||||
| +
 | ||||
| +if test "$libc_cv_asm_s390_min_z13_zarch" = yes ;
 | ||||
| +then
 | ||||
| +  $as_echo "#define HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT 1" >>confdefs.h
 | ||||
| +
 | ||||
| +fi
 | ||||
| +
 | ||||
|  test -n "$critic_missing" && as_fn_error $? " | ||||
|  *** $critic_missing" "$LINENO" 5 | ||||
| diff --git a/sysdeps/s390/configure.ac b/sysdeps/s390/configure.ac
 | ||||
| index 981f7a79dd7066fc..4dfb5574b49d5949 100644
 | ||||
| --- a/sysdeps/s390/configure.ac
 | ||||
| +++ b/sysdeps/s390/configure.ac
 | ||||
| @@ -135,5 +135,33 @@ then
 | ||||
|    AC_DEFINE(HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT) | ||||
|  fi | ||||
|   | ||||
| +AC_CACHE_CHECK(for S390 z13 zarch instruction support as default,
 | ||||
| +	       libc_cv_asm_s390_min_z13_zarch, [dnl
 | ||||
| +cat > conftest.c <<\EOF
 | ||||
| +int testinsn (void)
 | ||||
| +{
 | ||||
| +    int i;
 | ||||
| +    __asm__ ("vl %%v16,0(%%r15)\n\t"
 | ||||
| +	     "vlgvf %0,%%v16,0"
 | ||||
| +	     : "=d" (i) : : "memory", "v16");
 | ||||
| +    return i;
 | ||||
| +}
 | ||||
| +EOF
 | ||||
| +dnl
 | ||||
| +dnl test, if assembler supports S390 z13 zarch instructions as default
 | ||||
| +if AC_TRY_COMMAND([${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS --shared conftest.c
 | ||||
| +			-o conftest.o &> /dev/null]) ;
 | ||||
| +then
 | ||||
| +  libc_cv_asm_s390_min_z13_zarch=yes
 | ||||
| +else
 | ||||
| +  libc_cv_asm_s390_min_z13_zarch=no
 | ||||
| +fi
 | ||||
| +rm -f conftest* ])
 | ||||
| +
 | ||||
| +if test "$libc_cv_asm_s390_min_z13_zarch" = yes ;
 | ||||
| +then
 | ||||
| +  AC_DEFINE(HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT)
 | ||||
| +fi
 | ||||
| +
 | ||||
|  test -n "$critic_missing" && AC_MSG_ERROR([ | ||||
|  *** $critic_missing]) | ||||
							
								
								
									
										327
									
								
								SOURCES/glibc-rh1659438-13.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										327
									
								
								SOURCES/glibc-rh1659438-13.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,327 @@ | ||||
| commit cdd927d98cc38acf55e1c6594b5c9451df8f239f | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:08 2018 +0100 | ||||
| 
 | ||||
|     S390: Add z13 memmove ifunc variant. | ||||
|      | ||||
|     This patch introduces a z13 specific ifunc variant for memmove. | ||||
|     As the common code implementation, it checks if we can copy from | ||||
|     the beginning to the end - with z196 memcpy implementation - or | ||||
|     if we have to copy from the end to the beginning. | ||||
|     The latter case is done by using vector load/store instructions. | ||||
|      | ||||
|     If vector instructions are not available, the common-code is | ||||
|     used as fallback.  Therefore it is implemented in memmove-c with | ||||
|     a different name. | ||||
|     Furthermore the ifunc logic decides if we need the common-code | ||||
|     implementation at all.  If vector instructions are supported | ||||
|     due to the minimum architecture level set we can skip the | ||||
|     common-code ifunc variant. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add memmove-c. | ||||
|             * sysdeps/s390/ifunc-memcpy.h (HAVE_MEMMOVE_IFUNC, | ||||
|             HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT, MEMMOVE_DEFAULT, | ||||
|             HAVE_MEMMOVE_C, MEMMOVE_C,  HAVE_MEMMOVE_Z13, MEMMOVE_Z13): | ||||
|             New defines. | ||||
|             * sysdeps/s390/memcpy-z900.S: Add z13 memmove implementation. | ||||
|             * sysdeps/s390/memmove-c.c: New file. | ||||
|             * sysdeps/s390/memmove.c: Likewise. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Add ifunc variants for memmove. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index 838950a5ab958e31..3a7cccdf8f147398 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -33,5 +33,6 @@ endif
 | ||||
|  ifeq ($(subdir),string) | ||||
|  sysdep_routines += bzero memset memset-z900 \ | ||||
|  		   memcmp memcmp-z900 \ | ||||
| -		   mempcpy memcpy memcpy-z900
 | ||||
| +		   mempcpy memcpy memcpy-z900 \
 | ||||
| +		   memmove memmove-c
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h
 | ||||
| index 51c71baa2c0b0452..0e701968c8f39014 100644
 | ||||
| --- a/sysdeps/s390/ifunc-memcpy.h
 | ||||
| +++ b/sysdeps/s390/ifunc-memcpy.h
 | ||||
| @@ -43,6 +43,29 @@
 | ||||
|  # define HAVE_MEMCPY_Z196	HAVE_MEMCPY_IFUNC | ||||
|  #endif | ||||
|   | ||||
| +#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc)	\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_MEMMOVE_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_MEMMOVE_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT HAVE_MEMMOVE_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define MEMMOVE_DEFAULT	MEMMOVE_Z13
 | ||||
| +# define HAVE_MEMMOVE_C		0
 | ||||
| +# define HAVE_MEMMOVE_Z13	1
 | ||||
| +#else
 | ||||
| +# define MEMMOVE_DEFAULT	MEMMOVE_C
 | ||||
| +# define HAVE_MEMMOVE_C		1
 | ||||
| +# define HAVE_MEMMOVE_Z13	HAVE_MEMMOVE_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  #if HAVE_MEMCPY_Z900_G5 | ||||
|  # define MEMCPY_Z900_G5		__memcpy_default | ||||
|  # define MEMPCPY_Z900_G5	__mempcpy_default | ||||
| @@ -66,3 +89,15 @@
 | ||||
|  # define MEMCPY_Z196		NULL | ||||
|  # define MEMPCPY_Z196		NULL | ||||
|  #endif | ||||
| +
 | ||||
| +#if HAVE_MEMMOVE_C
 | ||||
| +# define MEMMOVE_C		__memmove_c
 | ||||
| +#else
 | ||||
| +# define MEMMOVE_C		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_MEMMOVE_Z13
 | ||||
| +# define MEMMOVE_Z13		__memmove_z13
 | ||||
| +#else
 | ||||
| +# define MEMMOVE_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/memcpy-z900.S b/sysdeps/s390/memcpy-z900.S
 | ||||
| index 3a50cf44d85d2417..bd3b1950ee442c0c 100644
 | ||||
| --- a/sysdeps/s390/memcpy-z900.S
 | ||||
| +++ b/sysdeps/s390/memcpy-z900.S
 | ||||
| @@ -182,6 +182,7 @@ ENTRY(MEMCPY_Z196)
 | ||||
|  # endif /* !defined __s390x__  */ | ||||
|  	ltgr    %r4,%r4 | ||||
|  	je      .L_Z196_4 | ||||
| +.L_Z196_start2:
 | ||||
|  	aghi    %r4,-1 | ||||
|  	srlg    %r5,%r4,8 | ||||
|  	ltgr    %r5,%r5 | ||||
| @@ -207,6 +208,75 @@ ENTRY(MEMCPY_Z196)
 | ||||
|  END(MEMCPY_Z196) | ||||
|  #endif /* HAVE_MEMCPY_Z196  */ | ||||
|   | ||||
| +#if HAVE_MEMMOVE_Z13
 | ||||
| +ENTRY(MEMMOVE_Z13)
 | ||||
| +	.machine "z13"
 | ||||
| +	.machinemode "zarch_nohighgprs"
 | ||||
| +# if !defined __s390x__
 | ||||
| +	/* Note: The 31bit dst and src pointers are prefixed with zeroes.  */
 | ||||
| +	llgfr	%r4,%r4
 | ||||
| +	llgfr	%r3,%r3
 | ||||
| +	llgfr	%r2,%r2
 | ||||
| +# endif /* !defined __s390x__ */
 | ||||
| +	sgrk	%r0,%r2,%r3
 | ||||
| +	clgijh	%r4,16,.L_MEMMOVE_Z13_LARGE
 | ||||
| +	aghik	%r5,%r4,-1
 | ||||
| +.L_MEMMOVE_Z13_SMALL:
 | ||||
| +	jl .L_MEMMOVE_Z13_END		/* Jump away if len was zero.  */
 | ||||
| +	/* Store up to 16 bytes with vll/vstl which needs the index
 | ||||
| +	   instead of lengths.  */
 | ||||
| +	vll	%v16,%r5,0(%r3)
 | ||||
| +	vstl	%v16,%r5,0(%r2)
 | ||||
| +.L_MEMMOVE_Z13_END:
 | ||||
| +	br      %r14
 | ||||
| +.L_MEMMOVE_Z13_LARGE:
 | ||||
| +	lgr     %r1,%r2			/* For memcpy: r1: Use as dest ;
 | ||||
| +					   r2: Return dest  */
 | ||||
| +	/* The unsigned comparison (dst - src >= len) determines if we can
 | ||||
| +	   execute the forward case with memcpy.  */
 | ||||
| +#if ! HAVE_MEMCPY_Z196
 | ||||
| +# error The z13 variant of memmove needs the z196 variant of memcpy!
 | ||||
| +#endif
 | ||||
| +	clgrjhe %r0,%r4,.L_Z196_start2
 | ||||
| +	risbgn	%r5,%r4,4,128+63,60	/* r5 = r4 / 16  */
 | ||||
| +	aghi	%r4,-16
 | ||||
| +	clgijhe	%r5,8,.L_MEMMOVE_Z13_LARGE_64B
 | ||||
| +.L_MEMMOVE_Z13_LARGE_16B_LOOP:
 | ||||
| +	/* Store at least 16 bytes with vl/vst. The number of 16byte blocks
 | ||||
| +	   is stored in r5.  */
 | ||||
| +	vl	%v16,0(%r4,%r3)
 | ||||
| +	vst	%v16,0(%r4,%r2)
 | ||||
| +	aghi	%r4,-16
 | ||||
| +	brctg	%r5,.L_MEMMOVE_Z13_LARGE_16B_LOOP
 | ||||
| +	aghik	%r5,%r4,15
 | ||||
| +	j	.L_MEMMOVE_Z13_SMALL
 | ||||
| +.L_MEMMOVE_Z13_LARGE_64B:
 | ||||
| +	/* Store at least 128 bytes with 4x vl/vst. The number of 64byte blocks
 | ||||
| +	   will be stored in r0.  */
 | ||||
| +	aghi	%r4,-48
 | ||||
| +	srlg	%r0,%r5,2		/* r5 = %r0 / 4
 | ||||
| +					   => Number of 64byte blocks.  */
 | ||||
| +.L_MEMMOVE_Z13_LARGE_64B_LOOP:
 | ||||
| +	vl	%v20,48(%r4,%r3)
 | ||||
| +	vl	%v19,32(%r4,%r3)
 | ||||
| +	vl	%v18,16(%r4,%r3)
 | ||||
| +	vl	%v17,0(%r4,%r3)
 | ||||
| +	vst	%v20,48(%r4,%r2)
 | ||||
| +	vst	%v19,32(%r4,%r2)
 | ||||
| +	vst	%v18,16(%r4,%r2)
 | ||||
| +	vst	%v17,0(%r4,%r2)
 | ||||
| +	aghi	%r4,-64
 | ||||
| +	brctg	%r0,.L_MEMMOVE_Z13_LARGE_64B_LOOP
 | ||||
| +	aghi	%r4,48
 | ||||
| +	/* Recalculate the number of 16byte blocks.  */
 | ||||
| +	risbg	%r5,%r5,62,128+63,0	/* r5 = r5 & 3
 | ||||
| +					   => Remaining 16byte blocks.  */
 | ||||
| +	jne	.L_MEMMOVE_Z13_LARGE_16B_LOOP
 | ||||
| +	aghik	%r5,%r4,15
 | ||||
| +	j	.L_MEMMOVE_Z13_SMALL
 | ||||
| +END(MEMMOVE_Z13)
 | ||||
| +#endif /* HAVE_MEMMOVE_Z13  */
 | ||||
| +
 | ||||
|  #if ! HAVE_MEMCPY_IFUNC | ||||
|  /* If we don't use ifunc, define an alias for mem[p]cpy here. | ||||
|     Otherwise see sysdeps/s390/mem[p]cpy.c.  */ | ||||
| @@ -215,10 +285,27 @@ strong_alias (MEMPCPY_DEFAULT, __mempcpy)
 | ||||
|  weak_alias (__mempcpy, mempcpy) | ||||
|  #endif | ||||
|   | ||||
| +#if ! HAVE_MEMMOVE_IFUNC
 | ||||
| +/* If we don't use ifunc, define an alias for memmove here.
 | ||||
| +   Otherwise see sysdeps/s390/memmove.c.  */
 | ||||
| +# if ! HAVE_MEMMOVE_C
 | ||||
| +/* If the c variant is needed, then sysdeps/s390/memmove-c.c
 | ||||
| +   defines memmove.
 | ||||
| +   Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it.  */
 | ||||
| +strong_alias (MEMMOVE_DEFAULT, memmove)
 | ||||
| +# endif
 | ||||
| +#endif
 | ||||
| +
 | ||||
|  #if defined SHARED && IS_IN (libc) | ||||
|  /* Defines the internal symbols. | ||||
|     Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c.  */ | ||||
|  strong_alias (MEMCPY_DEFAULT, __GI_memcpy) | ||||
|  strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy) | ||||
|  strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy) | ||||
| +# if ! HAVE_MEMMOVE_C
 | ||||
| +/* If the c variant is needed, then sysdeps/s390/memmove-c.c
 | ||||
| +   defines the internal symbol.
 | ||||
| +   Otherwise MEMMOVE_DEFAULT is implemented here and we have to define it.  */
 | ||||
| +strong_alias (MEMMOVE_DEFAULT, __GI_memmove)
 | ||||
| +# endif
 | ||||
|  #endif | ||||
| diff --git a/sysdeps/s390/memmove-c.c b/sysdeps/s390/memmove-c.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..be571093e019a38d
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/memmove-c.c
 | ||||
| @@ -0,0 +1,37 @@
 | ||||
| +/* Fallback C version of memmove.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-memcpy.h>
 | ||||
| +
 | ||||
| +#if HAVE_MEMMOVE_C
 | ||||
| +# if HAVE_MEMMOVE_IFUNC
 | ||||
| +/* If we use ifunc, then the memmove symbol is defined
 | ||||
| +   in sysdeps/s390/memmove.c and we use a different name here.
 | ||||
| +   Otherwise, we have to define memmove here or in
 | ||||
| +   sysdeps/s390/memcpy.S depending on the used default implementation.  */
 | ||||
| +#  define MEMMOVE MEMMOVE_C
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +/* Define the internal symbol.  */
 | ||||
| +#   undef libc_hidden_builtin_def
 | ||||
| +#   define libc_hidden_builtin_def(name)			\
 | ||||
| +  __hidden_ver1 (__memmove_c, __GI_memmove, __memmove_c);
 | ||||
| +#  endif
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# include <string/memmove.c>
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/memmove.c b/sysdeps/s390/memmove.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..ac34edf80f2678cd
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/memmove.c
 | ||||
| @@ -0,0 +1,44 @@
 | ||||
| +/* Multiple versions of memmove.
 | ||||
| +   Copyright (C) 2016-2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-memcpy.h>
 | ||||
| +
 | ||||
| +#if HAVE_MEMMOVE_IFUNC
 | ||||
| +/* If we don't use ifunc, an alias is defined for memmove
 | ||||
| +   in sysdeps/s390/memmove-c.c or sysdeps/s390/memcpy.S
 | ||||
| +   depending on the used default implementation.  */
 | ||||
| +# undef memmove
 | ||||
| +# define memmove __redirect_memmove
 | ||||
| +# include <string.h>
 | ||||
| +# include <ifunc-resolve.h>
 | ||||
| +# undef memmove
 | ||||
| +
 | ||||
| +# if HAVE_MEMMOVE_C
 | ||||
| +extern __typeof (__redirect_memmove) MEMMOVE_C attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if HAVE_MEMMOVE_Z13
 | ||||
| +extern __typeof (__redirect_memmove) MEMMOVE_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +s390_libc_ifunc_expr (__redirect_memmove, memmove,
 | ||||
| +		      (HAVE_MEMMOVE_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? MEMMOVE_Z13
 | ||||
| +		      : MEMMOVE_DEFAULT
 | ||||
| +		      )
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index 6969c480cc40e0e2..c05c63e00608dcd7 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -126,6 +126,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  	      ) | ||||
|  #endif /* HAVE_MEMCPY_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_MEMMOVE_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, memmove,
 | ||||
| +# if HAVE_MEMMOVE_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, memmove,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, MEMMOVE_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_MEMMOVE_C
 | ||||
| +		IFUNC_IMPL_ADD (array, i, memmove, 1, MEMMOVE_C)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_MEMMOVE_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
							
								
								
									
										263
									
								
								SOURCES/glibc-rh1659438-14.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										263
									
								
								SOURCES/glibc-rh1659438-14.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,263 @@ | ||||
| commit 8c25dddd2e32bce47dfe01ca51c8aab535dbe23d | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:09 2018 +0100 | ||||
| 
 | ||||
|     S390: Add z13 strstr ifunc variant. | ||||
|      | ||||
|     The new vector variant of strstr is using the common code | ||||
|     implementation, but instead of calling the default | ||||
|     str* / mem* functions, the vector variants are called. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add strstr variants. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Add ifunc variants for strstr. | ||||
|             * sysdeps/s390/ifunc-strstr.h: New file. | ||||
|             * sysdeps/s390/strstr.c: Likewise. | ||||
|             * sysdeps/s390/strstr-c.c: Likewise. | ||||
|             * sysdeps/s390/strstr-vx.c: Likewise. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index 3a7cccdf8f147398..4441e7a5cf6fa167 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -34,5 +34,6 @@ ifeq ($(subdir),string)
 | ||||
|  sysdep_routines += bzero memset memset-z900 \ | ||||
|  		   memcmp memcmp-z900 \ | ||||
|  		   mempcpy memcpy memcpy-z900 \ | ||||
| -		   memmove memmove-c
 | ||||
| +		   memmove memmove-c \
 | ||||
| +		   strstr strstr-vx strstr-c
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-strstr.h b/sysdeps/s390/ifunc-strstr.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..e6ccfd4e44a1a790
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/ifunc-strstr.h
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* strstr variant information on S/390 version.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#if defined USE_MULTIARCH && IS_IN (libc)		\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_STRSTR_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_STRSTR_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT HAVE_STRSTR_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_STRSTR_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define STRSTR_DEFAULT		STRSTR_Z13
 | ||||
| +# define HAVE_STRSTR_C		0
 | ||||
| +# define HAVE_STRSTR_Z13	1
 | ||||
| +#else
 | ||||
| +# define STRSTR_DEFAULT		STRSTR_C
 | ||||
| +# define HAVE_STRSTR_C		1
 | ||||
| +# define HAVE_STRSTR_Z13	HAVE_STRSTR_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRSTR_C
 | ||||
| +# define STRSTR_C		__strstr_c
 | ||||
| +#else
 | ||||
| +# define STRSTR_C		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRSTR_Z13
 | ||||
| +# define STRSTR_Z13		__strstr_vx
 | ||||
| +#else
 | ||||
| +# define STRSTR_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index c05c63e00608dcd7..14727f8fef5431dd 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -24,6 +24,7 @@
 | ||||
|  #include <ifunc-memset.h> | ||||
|  #include <ifunc-memcmp.h> | ||||
|  #include <ifunc-memcpy.h> | ||||
| +#include <ifunc-strstr.h>
 | ||||
|   | ||||
|  /* Maximum number of IFUNC implementations.  */ | ||||
|  #define MAX_IFUNC	3 | ||||
| @@ -138,6 +139,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  		) | ||||
|  #endif /* HAVE_MEMMOVE_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_STRSTR_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, strstr,
 | ||||
| +# if HAVE_STRSTR_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strstr,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, STRSTR_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_STRSTR_C
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strstr, 1, STRSTR_C)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_STRSTR_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
| diff --git a/sysdeps/s390/strstr-c.c b/sysdeps/s390/strstr-c.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..53717bfb276fed3d
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/strstr-c.c
 | ||||
| @@ -0,0 +1,32 @@
 | ||||
| +/* Default strstr implementation for S/390.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-strstr.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRSTR_C
 | ||||
| +# if HAVE_STRSTR_IFUNC
 | ||||
| +#  define STRSTR STRSTR_C
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_builtin_def
 | ||||
| +#   define libc_hidden_builtin_def(name)		\
 | ||||
| +  __hidden_ver1 (__strstr_c, __GI_strstr, __strstr_c);
 | ||||
| +#  endif
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# include <string/strstr.c>
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/strstr-vx.c b/sysdeps/s390/strstr-vx.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..effae9d5eb7d2fb1
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/strstr-vx.c
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* Default strstr implementation with vector string functions for S/390.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-strstr.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRSTR_Z13
 | ||||
| +# if HAVE_STRSTR_IFUNC
 | ||||
| +#  define STRSTR STRSTR_Z13
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_builtin_def
 | ||||
| +#   if HAVE_STRSTR_C
 | ||||
| +#    define libc_hidden_builtin_def(name)
 | ||||
| +#   else
 | ||||
| +#    define libc_hidden_builtin_def(name)		\
 | ||||
| +  __hidden_ver1 (__strstr_vx, __GI_strstr, __strstr_vx);
 | ||||
| +#   endif
 | ||||
| +#  endif
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# include <string.h>
 | ||||
| +
 | ||||
| +# ifdef USE_MULTIARCH
 | ||||
| +extern __typeof (strchr) __strchr_vx attribute_hidden;
 | ||||
| +#  define strchr __strchr_vx
 | ||||
| +
 | ||||
| +extern __typeof (strlen) __strlen_vx attribute_hidden;
 | ||||
| +#  define strlen __strlen_vx
 | ||||
| +
 | ||||
| +extern __typeof (__strnlen) __strnlen_vx attribute_hidden;
 | ||||
| +#  define __strnlen __strnlen_vx
 | ||||
| +
 | ||||
| +extern __typeof (memcmp) __memcmp_z196 attribute_hidden;
 | ||||
| +#  define memcmp __memcmp_z196
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# include <string/strstr.c>
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/strstr.c b/sysdeps/s390/strstr.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..f8432349a7254cc6
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/strstr.c
 | ||||
| @@ -0,0 +1,40 @@
 | ||||
| +/* Multiple versions of strstr.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-strstr.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRSTR_IFUNC
 | ||||
| +# define strstr __redirect_strstr
 | ||||
| +# include <string.h>
 | ||||
| +# include <ifunc-resolve.h>
 | ||||
| +# undef strstr
 | ||||
| +
 | ||||
| +# if HAVE_STRSTR_C
 | ||||
| +extern __typeof (__redirect_strstr) STRSTR_C attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if HAVE_STRSTR_Z13
 | ||||
| +extern __typeof (__redirect_strstr) STRSTR_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +s390_libc_ifunc_expr (__redirect_strstr, strstr,
 | ||||
| +		      (HAVE_STRSTR_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? STRSTR_Z13
 | ||||
| +		      : STRSTR_DEFAULT
 | ||||
| +		      )
 | ||||
| +#endif
 | ||||
							
								
								
									
										290
									
								
								SOURCES/glibc-rh1659438-15.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										290
									
								
								SOURCES/glibc-rh1659438-15.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,290 @@ | ||||
| commit d2c4c403feddd6f0b9dbf31ca7541b37f90ee30a | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:09 2018 +0100 | ||||
| 
 | ||||
|     S390: Add z13 memmem ifunc variant. | ||||
|      | ||||
|     The new vector variant of memmem is using the common code | ||||
|     implementation, but instead of calling the default | ||||
|     mem* functions, the vector variants are called. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add memmem variants. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Add ifunc variants for memmem. | ||||
|             * sysdeps/s390/ifunc-memmem.h: New file. | ||||
|             * sysdeps/s390/memmem.c: Likewise. | ||||
|             * sysdeps/s390/memmem-c.c: Likewise. | ||||
|             * sysdeps/s390/memmem-vx.c: Likewise. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index 4441e7a5cf6fa167..47d606d3d5d99274 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -35,5 +35,6 @@ sysdep_routines += bzero memset memset-z900 \
 | ||||
|  		   memcmp memcmp-z900 \ | ||||
|  		   mempcpy memcpy memcpy-z900 \ | ||||
|  		   memmove memmove-c \ | ||||
| -		   strstr strstr-vx strstr-c
 | ||||
| +		   strstr strstr-vx strstr-c \
 | ||||
| +		   memmem memmem-vx memmem-c
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-memmem.h b/sysdeps/s390/ifunc-memmem.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..0f860d8d40080acf
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/ifunc-memmem.h
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* memmem variant information on S/390 version.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#if defined USE_MULTIARCH && IS_IN (libc)		\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_MEMMEM_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_MEMMEM_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT HAVE_MEMMEM_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define MEMMEM_DEFAULT		MEMMEM_Z13
 | ||||
| +# define HAVE_MEMMEM_C		0
 | ||||
| +# define HAVE_MEMMEM_Z13	1
 | ||||
| +#else
 | ||||
| +# define MEMMEM_DEFAULT		MEMMEM_C
 | ||||
| +# define HAVE_MEMMEM_C		1
 | ||||
| +# define HAVE_MEMMEM_Z13	HAVE_MEMMEM_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_MEMMEM_C
 | ||||
| +# define MEMMEM_C		__memmem_c
 | ||||
| +#else
 | ||||
| +# define MEMMEM_C		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_MEMMEM_Z13
 | ||||
| +# define MEMMEM_Z13		__memmem_vx
 | ||||
| +#else
 | ||||
| +# define MEMMEM_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/memmem-c.c b/sysdeps/s390/memmem-c.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..1d8ffefcb840b8d2
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/memmem-c.c
 | ||||
| @@ -0,0 +1,47 @@
 | ||||
| +/* Default memmem implementation for S/390.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-memmem.h>
 | ||||
| +
 | ||||
| +#if HAVE_MEMMEM_C
 | ||||
| +# if HAVE_MEMMEM_IFUNC
 | ||||
| +#  include <string.h>
 | ||||
| +
 | ||||
| +#  ifndef _LIBC
 | ||||
| +#   define memmem MEMMEM_C
 | ||||
| +#  else
 | ||||
| +#   define __memmem MEMMEM_C
 | ||||
| +#  endif
 | ||||
| +
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_def
 | ||||
| +#   define libc_hidden_def(name)				\
 | ||||
| +  strong_alias (__memmem_c, __memmem_c_1);			\
 | ||||
| +  __hidden_ver1 (__memmem_c, __GI___memmem, __memmem_c);
 | ||||
| +
 | ||||
| +#   undef libc_hidden_weak
 | ||||
| +#   define libc_hidden_weak(name)					\
 | ||||
| +  __hidden_ver1 (__memmem_c_1, __GI_memmem, __memmem_c_1) __attribute__((weak));
 | ||||
| +#  endif
 | ||||
| +
 | ||||
| +#  undef weak_alias
 | ||||
| +#  define weak_alias(a, b)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# include <string/memmem.c>
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/memmem-vx.c b/sysdeps/s390/memmem-vx.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..af6e200e4e0af1a5
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/memmem-vx.c
 | ||||
| @@ -0,0 +1,61 @@
 | ||||
| +/* Default memmem implementation with vector string functions for S/390.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-memmem.h>
 | ||||
| +
 | ||||
| +#if HAVE_MEMMEM_Z13
 | ||||
| +# include <string.h>
 | ||||
| +# if HAVE_MEMMEM_IFUNC
 | ||||
| +
 | ||||
| +#  ifndef _LIBC
 | ||||
| +#   define memmem MEMMEM_Z13
 | ||||
| +#  else
 | ||||
| +#   define __memmem MEMMEM_Z13
 | ||||
| +#  endif
 | ||||
| +
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_def
 | ||||
| +#   undef libc_hidden_weak
 | ||||
| +
 | ||||
| +#   if HAVE_MEMMEM_C
 | ||||
| +#    define libc_hidden_def(name)
 | ||||
| +#    define libc_hidden_weak(name)
 | ||||
| +#   else
 | ||||
| +#    define libc_hidden_def(name)				\
 | ||||
| +  strong_alias (__memmem_vx, __memmem_vx_1);			\
 | ||||
| +  __hidden_ver1 (__memmem_vx, __GI___memmem, __memmem_vx);
 | ||||
| +
 | ||||
| +#    define libc_hidden_weak(name)					\
 | ||||
| +  __hidden_ver1 (__memmem_vx_1, __GI_memmem, __memmem_vx_1) __attribute__((weak));
 | ||||
| +#   endif
 | ||||
| +#  endif
 | ||||
| +
 | ||||
| +#  undef weak_alias
 | ||||
| +#  define weak_alias(a, b)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# ifdef USE_MULTIARCH
 | ||||
| +extern __typeof (memchr) __memchr_vx attribute_hidden;
 | ||||
| +# define memchr __memchr_vx
 | ||||
| +
 | ||||
| +extern __typeof (memcmp) __memcmp_z196 attribute_hidden;
 | ||||
| +# define memcmp __memcmp_z196
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# include <string/memmem.c>
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/memmem.c b/sysdeps/s390/memmem.c
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..8c50b3f403eb8d1f
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/memmem.c
 | ||||
| @@ -0,0 +1,43 @@
 | ||||
| +/* Multiple versions of memmem.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#include <ifunc-memmem.h>
 | ||||
| +
 | ||||
| +#if HAVE_MEMMEM_IFUNC
 | ||||
| +# define memmem __redirect_memmem
 | ||||
| +# define __memmem __redirect___memmem
 | ||||
| +# include <string.h>
 | ||||
| +# include <ifunc-resolve.h>
 | ||||
| +# undef memmem
 | ||||
| +# undef __memmem
 | ||||
| +
 | ||||
| +# if HAVE_MEMMEM_C
 | ||||
| +extern __typeof (__redirect_memmem) MEMMEM_C attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if HAVE_MEMMEM_Z13
 | ||||
| +extern __typeof (__redirect_memmem) MEMMEM_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +s390_libc_ifunc_expr (__redirect_memmem, __memmem,
 | ||||
| +		      (HAVE_MEMMEM_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? MEMMEM_Z13
 | ||||
| +		      : MEMMEM_DEFAULT
 | ||||
| +		      )
 | ||||
| +weak_alias (__memmem, memmem)
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index 14727f8fef5431dd..da8696d917abf51c 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -25,6 +25,7 @@
 | ||||
|  #include <ifunc-memcmp.h> | ||||
|  #include <ifunc-memcpy.h> | ||||
|  #include <ifunc-strstr.h> | ||||
| +#include <ifunc-memmem.h>
 | ||||
|   | ||||
|  /* Maximum number of IFUNC implementations.  */ | ||||
|  #define MAX_IFUNC	3 | ||||
| @@ -151,6 +152,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  		) | ||||
|  #endif /* HAVE_STRSTR_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_MEMMEM_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, memmem,
 | ||||
| +# if HAVE_MEMMEM_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, memmem,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, MEMMEM_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_MEMMEM_C
 | ||||
| +		IFUNC_IMPL_ADD (array, i, memmem, 1, MEMMEM_C)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_MEMMEM_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
							
								
								
									
										259
									
								
								SOURCES/glibc-rh1659438-16.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										259
									
								
								SOURCES/glibc-rh1659438-16.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,259 @@ | ||||
| commit ff3ca3743a00af749258cc242457b648d65a1537 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:10 2018 +0100 | ||||
| 
 | ||||
|     S390: Refactor strlen ifunc handling. | ||||
|      | ||||
|     The ifunc handling for strlen is adjusted in order to omit ifunc | ||||
|     variants if those will never be used as the minimum architecture level | ||||
|     already supports newer CPUs by default. | ||||
|     Glibc internal calls will then also use the "newer" ifunc variant. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/multiarch/Makefile | ||||
|             (sysdep_routines): Remove strlen variants. | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add strlen variants. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Refactor ifunc handling for strlen. | ||||
|             * sysdeps/s390/multiarch/strlen-c.c: Move to ... | ||||
|             * sysdeps/s390/strlen-c.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/strlen-vx.S: Move to ... | ||||
|             * sysdeps/s390/strlen-vx.S: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/strlen.c: Move to ... | ||||
|             * sysdeps/s390/strlen.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/ifunc-strlen.h: New file. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index 47d606d3d5d99274..600d8e629df7090e 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -36,5 +36,6 @@ sysdep_routines += bzero memset memset-z900 \
 | ||||
|  		   mempcpy memcpy memcpy-z900 \ | ||||
|  		   memmove memmove-c \ | ||||
|  		   strstr strstr-vx strstr-c \ | ||||
| -		   memmem memmem-vx memmem-c
 | ||||
| +		   memmem memmem-vx memmem-c \
 | ||||
| +		   strlen strlen-vx strlen-c
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-strlen.h b/sysdeps/s390/ifunc-strlen.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..f2070596636f29a9
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/ifunc-strlen.h
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* strlen variant information on S/390 version.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#if defined USE_MULTIARCH && IS_IN (libc)		\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_STRLEN_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_STRLEN_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT HAVE_STRLEN_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_STRLEN_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define STRLEN_DEFAULT		STRLEN_Z13
 | ||||
| +# define HAVE_STRLEN_C		0
 | ||||
| +# define HAVE_STRLEN_Z13	1
 | ||||
| +#else
 | ||||
| +# define STRLEN_DEFAULT		STRLEN_C
 | ||||
| +# define HAVE_STRLEN_C		1
 | ||||
| +# define HAVE_STRLEN_Z13	HAVE_STRLEN_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRLEN_C
 | ||||
| +# define STRLEN_C		__strlen_c
 | ||||
| +#else
 | ||||
| +# define STRLEN_C		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRLEN_Z13
 | ||||
| +# define STRLEN_Z13		__strlen_vx
 | ||||
| +#else
 | ||||
| +# define STRLEN_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
 | ||||
| index 24949cd3a88b8015..601523919c235f76 100644
 | ||||
| --- a/sysdeps/s390/multiarch/Makefile
 | ||||
| +++ b/sysdeps/s390/multiarch/Makefile
 | ||||
| @@ -1,6 +1,5 @@
 | ||||
|  ifeq ($(subdir),string) | ||||
| -sysdep_routines += strlen strlen-vx strlen-c \
 | ||||
| -		   strnlen strnlen-vx strnlen-c \
 | ||||
| +sysdep_routines += strnlen strnlen-vx strnlen-c \
 | ||||
|  		   strcpy strcpy-vx \ | ||||
|  		   stpcpy stpcpy-vx stpcpy-c \ | ||||
|  		   strncpy strncpy-vx \ | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index da8696d917abf51c..c531be4bc7eb3f55 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -26,6 +26,7 @@
 | ||||
|  #include <ifunc-memcpy.h> | ||||
|  #include <ifunc-strstr.h> | ||||
|  #include <ifunc-memmem.h> | ||||
| +#include <ifunc-strlen.h>
 | ||||
|   | ||||
|  /* Maximum number of IFUNC implementations.  */ | ||||
|  #define MAX_IFUNC	3 | ||||
| @@ -164,6 +165,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  		) | ||||
|  #endif /* HAVE_MEMMEM_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_STRLEN_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, strlen,
 | ||||
| +# if HAVE_STRLEN_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strlen,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, STRLEN_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_STRLEN_C
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strlen, 1, STRLEN_C)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_STRLEN_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
| @@ -172,7 +185,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  			      __##FUNC##_vx)				\ | ||||
|  	      IFUNC_IMPL_ADD (array, i, FUNC, 1, __##FUNC##_c)) | ||||
|   | ||||
| -  IFUNC_VX_IMPL (strlen);
 | ||||
|    IFUNC_VX_IMPL (wcslen); | ||||
|   | ||||
|    IFUNC_VX_IMPL (strnlen); | ||||
| diff --git a/sysdeps/s390/multiarch/strlen-c.c b/sysdeps/s390/strlen-c.c
 | ||||
| similarity index 78% | ||||
| rename from sysdeps/s390/multiarch/strlen-c.c | ||||
| rename to sysdeps/s390/strlen-c.c | ||||
| index a2c8e43624a9bc91..b4569701af96f4a9 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strlen-c.c
 | ||||
| +++ b/sysdeps/s390/strlen-c.c
 | ||||
| @@ -16,13 +16,17 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| -# define STRLEN  __strlen_c
 | ||||
| -# ifdef SHARED
 | ||||
| -#  undef libc_hidden_builtin_def
 | ||||
| -#  define libc_hidden_builtin_def(name)			\
 | ||||
| +#include <ifunc-strlen.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRLEN_C
 | ||||
| +# if HAVE_STRLEN_IFUNC
 | ||||
| +#  define STRLEN STRLEN_C
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_builtin_def
 | ||||
| +#   define libc_hidden_builtin_def(name)		\
 | ||||
|    __hidden_ver1 (__strlen_c, __GI_strlen, __strlen_c); | ||||
| -# endif /* SHARED */
 | ||||
| +#  endif
 | ||||
| +# endif
 | ||||
|   | ||||
|  # include <string/strlen.c> | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/strlen-vx.S b/sysdeps/s390/strlen-vx.S
 | ||||
| similarity index 90% | ||||
| rename from sysdeps/s390/multiarch/strlen-vx.S | ||||
| rename to sysdeps/s390/strlen-vx.S | ||||
| index 9308b332371dcdaa..39ef43107d11ec73 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strlen-vx.S
 | ||||
| +++ b/sysdeps/s390/strlen-vx.S
 | ||||
| @@ -16,7 +16,8 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-strlen.h>
 | ||||
| +#if HAVE_STRLEN_Z13
 | ||||
|   | ||||
|  # include "sysdep.h" | ||||
|  # include "asm-syntax.h" | ||||
| @@ -34,7 +35,7 @@
 | ||||
|     -r5=current_len and return_value | ||||
|     -v16=part of s | ||||
|  */ | ||||
| -ENTRY(__strlen_vx)
 | ||||
| +ENTRY(STRLEN_Z13)
 | ||||
|  	.machine "z13" | ||||
|  	.machinemode "zarch_nohighgprs" | ||||
|   | ||||
| @@ -80,5 +81,13 @@ ENTRY(__strlen_vx)
 | ||||
|  	vlgvb	%r2,%v16,7	/* Load byte index of zero.  */ | ||||
|  	algr	%r2,%r5 | ||||
|  	br	%r14 | ||||
| -END(__strlen_vx)
 | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +END(STRLEN_Z13)
 | ||||
| +
 | ||||
| +# if ! HAVE_STRLEN_IFUNC
 | ||||
| +strong_alias (STRLEN_Z13, strlen)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if ! HAVE_STRLEN_C && defined SHARED && IS_IN (libc)
 | ||||
| +strong_alias (STRLEN_Z13, __GI_strlen)
 | ||||
| +# endif
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/strlen.c
 | ||||
| similarity index 69% | ||||
| rename from sysdeps/s390/multiarch/strlen.c | ||||
| rename to sysdeps/s390/strlen.c | ||||
| index 0edf8b7d0231cf31..6ba0fe86fe9789f0 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strlen.c
 | ||||
| +++ b/sysdeps/s390/strlen.c
 | ||||
| @@ -16,14 +16,25 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-strlen.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRLEN_IFUNC
 | ||||
|  # define strlen __redirect_strlen | ||||
|  # include <string.h> | ||||
|  # include <ifunc-resolve.h> | ||||
|  # undef strlen | ||||
|   | ||||
| -s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen)
 | ||||
| +# if HAVE_STRLEN_C
 | ||||
| +extern __typeof (__redirect_strlen) STRLEN_C attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if HAVE_STRLEN_Z13
 | ||||
| +extern __typeof (__redirect_strlen) STRLEN_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
|   | ||||
| -#else
 | ||||
| -# include <string/strlen.c>
 | ||||
| -#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
 | ||||
| +s390_libc_ifunc_expr (__redirect_strlen, strlen,
 | ||||
| +		      (HAVE_STRLEN_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? STRLEN_Z13
 | ||||
| +		      : STRLEN_DEFAULT
 | ||||
| +		      )
 | ||||
| +#endif
 | ||||
							
								
								
									
										269
									
								
								SOURCES/glibc-rh1659438-17.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										269
									
								
								SOURCES/glibc-rh1659438-17.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,269 @@ | ||||
| commit de10e44dda686e3ed6a7a1463869df846ea39825 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:10 2018 +0100 | ||||
| 
 | ||||
|     S390: Refactor strnlen ifunc handling. | ||||
|      | ||||
|     The ifunc handling for strnlen is adjusted in order to omit ifunc | ||||
|     variants if those will never be used as the minimum architecture level | ||||
|     already supports newer CPUs by default. | ||||
|     Glibc internal calls will then also use the "newer" ifunc variant. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/multiarch/Makefile | ||||
|             (sysdep_routines): Remove strnlen variants. | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add strnlen variants. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Refactor ifunc handling for strnlen. | ||||
|             * sysdeps/s390/multiarch/strnlen-c.c: Move to ... | ||||
|             * sysdeps/s390/strnlen-c.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/strnlen-vx.S: Move to ... | ||||
|             * sysdeps/s390/strnlen-vx.S: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/strnlen.c: Move to ... | ||||
|             * sysdeps/s390/strnlen.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/ifunc-strnlen.h: New file. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index 600d8e629df7090e..f092355743e3908f 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -37,5 +37,6 @@ sysdep_routines += bzero memset memset-z900 \
 | ||||
|  		   memmove memmove-c \ | ||||
|  		   strstr strstr-vx strstr-c \ | ||||
|  		   memmem memmem-vx memmem-c \ | ||||
| -		   strlen strlen-vx strlen-c
 | ||||
| +		   strlen strlen-vx strlen-c \
 | ||||
| +		   strnlen strnlen-vx strnlen-c
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-strnlen.h b/sysdeps/s390/ifunc-strnlen.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..e92329888773304d
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/ifunc-strnlen.h
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* strnlen variant information on S/390 version.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#if defined USE_MULTIARCH && IS_IN (libc)		\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_STRNLEN_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_STRNLEN_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT HAVE_STRNLEN_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define STRNLEN_DEFAULT	STRNLEN_Z13
 | ||||
| +# define HAVE_STRNLEN_C		0
 | ||||
| +# define HAVE_STRNLEN_Z13	1
 | ||||
| +#else
 | ||||
| +# define STRNLEN_DEFAULT	STRNLEN_C
 | ||||
| +# define HAVE_STRNLEN_C		1
 | ||||
| +# define HAVE_STRNLEN_Z13	HAVE_STRNLEN_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRNLEN_C
 | ||||
| +# define STRNLEN_C		__strnlen_c
 | ||||
| +#else
 | ||||
| +# define STRNLEN_C		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRNLEN_Z13
 | ||||
| +# define STRNLEN_Z13		__strnlen_vx
 | ||||
| +#else
 | ||||
| +# define STRNLEN_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
 | ||||
| index 601523919c235f76..35ba223c5d4fb52f 100644
 | ||||
| --- a/sysdeps/s390/multiarch/Makefile
 | ||||
| +++ b/sysdeps/s390/multiarch/Makefile
 | ||||
| @@ -1,6 +1,5 @@
 | ||||
|  ifeq ($(subdir),string) | ||||
| -sysdep_routines += strnlen strnlen-vx strnlen-c \
 | ||||
| -		   strcpy strcpy-vx \
 | ||||
| +sysdep_routines += strcpy strcpy-vx \
 | ||||
|  		   stpcpy stpcpy-vx stpcpy-c \ | ||||
|  		   strncpy strncpy-vx \ | ||||
|  		   stpncpy stpncpy-vx stpncpy-c \ | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index c531be4bc7eb3f55..680e5b738bfb7f32 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -27,6 +27,7 @@
 | ||||
|  #include <ifunc-strstr.h> | ||||
|  #include <ifunc-memmem.h> | ||||
|  #include <ifunc-strlen.h> | ||||
| +#include <ifunc-strnlen.h>
 | ||||
|   | ||||
|  /* Maximum number of IFUNC implementations.  */ | ||||
|  #define MAX_IFUNC	3 | ||||
| @@ -177,6 +178,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  		) | ||||
|  #endif /* HAVE_STRLEN_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_STRNLEN_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, strnlen,
 | ||||
| +# if HAVE_STRNLEN_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strnlen,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, STRNLEN_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_STRNLEN_C
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strnlen, 1, STRNLEN_C)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_STRNLEN_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
| @@ -187,7 +200,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|   | ||||
|    IFUNC_VX_IMPL (wcslen); | ||||
|   | ||||
| -  IFUNC_VX_IMPL (strnlen);
 | ||||
|    IFUNC_VX_IMPL (wcsnlen); | ||||
|   | ||||
|    IFUNC_VX_IMPL (strcpy); | ||||
| diff --git a/sysdeps/s390/multiarch/strnlen-c.c b/sysdeps/s390/strnlen-c.c
 | ||||
| similarity index 81% | ||||
| rename from sysdeps/s390/multiarch/strnlen-c.c | ||||
| rename to sysdeps/s390/strnlen-c.c | ||||
| index 353e83ed356ca080..c2d887f1e4f504e8 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strnlen-c.c
 | ||||
| +++ b/sysdeps/s390/strnlen-c.c
 | ||||
| @@ -16,15 +16,19 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| -# define STRNLEN  __strnlen_c
 | ||||
| -# ifdef SHARED
 | ||||
| -#  undef libc_hidden_def
 | ||||
| -#  define libc_hidden_def(name)					\
 | ||||
| +#include <ifunc-strnlen.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRNLEN_C
 | ||||
| +# if HAVE_STRNLEN_IFUNC
 | ||||
| +#  define STRNLEN STRNLEN_C
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_def
 | ||||
| +#   define libc_hidden_def(name)					\
 | ||||
|    __hidden_ver1 (__strnlen_c, __GI_strnlen, __strnlen_c);	\ | ||||
|    strong_alias (__strnlen_c, __strnlen_c_1);			\ | ||||
|    __hidden_ver1 (__strnlen_c_1, __GI___strnlen, __strnlen_c_1); | ||||
| -# endif /* SHARED */
 | ||||
| +#  endif
 | ||||
| +# endif
 | ||||
|   | ||||
|  # include <string/strnlen.c> | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/strnlen-vx.S b/sysdeps/s390/strnlen-vx.S
 | ||||
| similarity index 90% | ||||
| rename from sysdeps/s390/multiarch/strnlen-vx.S | ||||
| rename to sysdeps/s390/strnlen-vx.S | ||||
| index fc659a956cfc1fa1..0b8fe3da342f6803 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strnlen-vx.S
 | ||||
| +++ b/sysdeps/s390/strnlen-vx.S
 | ||||
| @@ -16,7 +16,9 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-strnlen.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRNLEN_Z13
 | ||||
|   | ||||
|  # include "sysdep.h" | ||||
|  # include "asm-syntax.h" | ||||
| @@ -34,7 +36,7 @@
 | ||||
|     -r5=current_len and return_value | ||||
|     -v16=part of s | ||||
|  */ | ||||
| -ENTRY(__strnlen_vx)
 | ||||
| +ENTRY(STRNLEN_Z13)
 | ||||
|  	.machine "z13" | ||||
|  	.machinemode "zarch_nohighgprs" | ||||
|   | ||||
| @@ -130,5 +132,16 @@ ENTRY(__strnlen_vx)
 | ||||
|  	clgrjl	%r1,%r3,.Lloop64 | ||||
|   | ||||
|  	j	.Llt64 | ||||
| -END(__strnlen_vx)
 | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +END(STRNLEN_Z13)
 | ||||
| +
 | ||||
| +# if ! HAVE_STRNLEN_IFUNC
 | ||||
| +strong_alias (STRNLEN_Z13, __strnlen)
 | ||||
| +weak_alias (__strnlen, strnlen)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if ! HAVE_STRNLEN_C && defined SHARED && IS_IN (libc)
 | ||||
| +strong_alias (STRNLEN_Z13, __GI_strnlen)
 | ||||
| +strong_alias (STRNLEN_Z13, __GI___strnlen)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +#endif /* HAVE_STRNLEN_Z13  */
 | ||||
| diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/strnlen.c
 | ||||
| similarity index 69% | ||||
| rename from sysdeps/s390/multiarch/strnlen.c | ||||
| rename to sysdeps/s390/strnlen.c | ||||
| index 0f9cff5d69b017ae..aa4953d5035bc2fc 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strnlen.c
 | ||||
| +++ b/sysdeps/s390/strnlen.c
 | ||||
| @@ -16,7 +16,9 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-strnlen.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRNLEN_IFUNC
 | ||||
|  # define strnlen __redirect_strnlen | ||||
|  # define __strnlen __redirect___strnlen | ||||
|  # include <string.h> | ||||
| @@ -24,9 +26,18 @@
 | ||||
|  # undef __strnlen | ||||
|  # include <ifunc-resolve.h> | ||||
|   | ||||
| -s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen)
 | ||||
| -weak_alias (__strnlen, strnlen)
 | ||||
| +# if HAVE_STRNLEN_C
 | ||||
| +extern __typeof (__redirect_strnlen) STRNLEN_C attribute_hidden;
 | ||||
| +# endif
 | ||||
|   | ||||
| -#else
 | ||||
| -# include <string/strnlen.c>
 | ||||
| -#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
 | ||||
| +# if HAVE_STRNLEN_Z13
 | ||||
| +extern __typeof (__redirect_strnlen) STRNLEN_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +s390_libc_ifunc_expr (__redirect___strnlen, __strnlen,
 | ||||
| +		      (HAVE_STRNLEN_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? STRNLEN_Z13
 | ||||
| +		      : STRNLEN_DEFAULT
 | ||||
| +		      )
 | ||||
| +weak_alias (__strnlen, strnlen)
 | ||||
| +#endif /* HAVE_STRNLEN_IFUNC  */
 | ||||
							
								
								
									
										398
									
								
								SOURCES/glibc-rh1659438-18.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										398
									
								
								SOURCES/glibc-rh1659438-18.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,398 @@ | ||||
| commit 914a4e05572e108201d71dcd3e47da8aeeecd70d | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:10 2018 +0100 | ||||
| 
 | ||||
|     S390: Refactor strcpy ifunc handling. | ||||
|      | ||||
|     The ifunc handling for strcpy is adjusted in order to omit ifunc | ||||
|     variants if those will never be used as the minimum architecture level | ||||
|     already supports newer CPUs by default. | ||||
|     Glibc internal calls will then also use the "newer" ifunc variant. | ||||
|      | ||||
|     Note: The fallback s390-32/s390-64 ifunc variants with mvst instruction | ||||
|     are now moved to the unified strcpy-z900.S file which can be used for | ||||
|     31/64bit. The s390-32/s390-64 files multiarch/strcpy.c and strcpy.S | ||||
|     are deleted. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/multiarch/Makefile | ||||
|             (sysdep_routines): Remove strcpy variants. | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add strcpy variants. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Refactor ifunc handling for strcpy. | ||||
|             * sysdeps/s390/multiarch/strcpy-vx.S: Move to ... | ||||
|             * sysdeps/s390/strcpy-vx.S: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/strcpy.c: Move to ... | ||||
|             * sysdeps/s390/strcpy.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/ifunc-strcpy.h: New file. | ||||
|             * sysdeps/s390/s390-64/strcpy.S: Move to ... | ||||
|             * sysdeps/s390/strcpy-z900.S: ... here and adjust to be usable | ||||
|             for 31/64bit and ifunc handling. | ||||
|             * sysdeps/s390/s390-32/multiarch/strcpy.c: Delete file. | ||||
|             * sysdeps/s390/s390-64/multiarch/strcpy.c: Likewise. | ||||
|             * sysdeps/s390/s390-32/strcpy.S: Likewise. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index f092355743e3908f..e4191319531ecb01 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -38,5 +38,6 @@ sysdep_routines += bzero memset memset-z900 \
 | ||||
|  		   strstr strstr-vx strstr-c \ | ||||
|  		   memmem memmem-vx memmem-c \ | ||||
|  		   strlen strlen-vx strlen-c \ | ||||
| -		   strnlen strnlen-vx strnlen-c
 | ||||
| +		   strnlen strnlen-vx strnlen-c \
 | ||||
| +		   strcpy strcpy-vx strcpy-z900
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-strcpy.h b/sysdeps/s390/ifunc-strcpy.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..85e45556e6a61dd5
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/ifunc-strcpy.h
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* strcpy variant information on S/390 version.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#if defined USE_MULTIARCH && IS_IN (libc)		\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_STRCPY_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_STRCPY_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT HAVE_STRCPY_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_STRCPY_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define STRCPY_DEFAULT		STRCPY_Z13
 | ||||
| +# define HAVE_STRCPY_Z900_G5	0
 | ||||
| +# define HAVE_STRCPY_Z13	1
 | ||||
| +#else
 | ||||
| +# define STRCPY_DEFAULT		STRCPY_Z900_G5
 | ||||
| +# define HAVE_STRCPY_Z900_G5	1
 | ||||
| +# define HAVE_STRCPY_Z13	HAVE_STRCPY_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRCPY_Z900_G5
 | ||||
| +# define STRCPY_Z900_G5		__strcpy_default
 | ||||
| +#else
 | ||||
| +# define STRCPY_Z900_G5		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STRCPY_Z13
 | ||||
| +# define STRCPY_Z13		__strcpy_vx
 | ||||
| +#else
 | ||||
| +# define STRCPY_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
 | ||||
| index 35ba223c5d4fb52f..50f7f0b78df723bb 100644
 | ||||
| --- a/sysdeps/s390/multiarch/Makefile
 | ||||
| +++ b/sysdeps/s390/multiarch/Makefile
 | ||||
| @@ -1,6 +1,5 @@
 | ||||
|  ifeq ($(subdir),string) | ||||
| -sysdep_routines += strcpy strcpy-vx \
 | ||||
| -		   stpcpy stpcpy-vx stpcpy-c \
 | ||||
| +sysdep_routines += stpcpy stpcpy-vx stpcpy-c \
 | ||||
|  		   strncpy strncpy-vx \ | ||||
|  		   stpncpy stpncpy-vx stpncpy-c \ | ||||
|  		   strcat strcat-vx strcat-c \ | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index 680e5b738bfb7f32..1784372db9828463 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -28,6 +28,7 @@
 | ||||
|  #include <ifunc-memmem.h> | ||||
|  #include <ifunc-strlen.h> | ||||
|  #include <ifunc-strnlen.h> | ||||
| +#include <ifunc-strcpy.h>
 | ||||
|   | ||||
|  /* Maximum number of IFUNC implementations.  */ | ||||
|  #define MAX_IFUNC	3 | ||||
| @@ -190,6 +191,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  		) | ||||
|  #endif /* HAVE_STRNLEN_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_STRCPY_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, strcpy,
 | ||||
| +# if HAVE_STRCPY_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strcpy,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, STRCPY_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_STRCPY_Z900_G5
 | ||||
| +		IFUNC_IMPL_ADD (array, i, strcpy, 1, STRCPY_Z900_G5)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_STRCPY_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
| @@ -202,7 +215,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|   | ||||
|    IFUNC_VX_IMPL (wcsnlen); | ||||
|   | ||||
| -  IFUNC_VX_IMPL (strcpy);
 | ||||
|    IFUNC_VX_IMPL (wcscpy); | ||||
|   | ||||
|    IFUNC_VX_IMPL (stpcpy); | ||||
| diff --git a/sysdeps/s390/s390-32/multiarch/strcpy.c b/sysdeps/s390/s390-32/multiarch/strcpy.c
 | ||||
| deleted file mode 100644 | ||||
| index 6a22e31a03c8c1c4..0000000000000000
 | ||||
| --- a/sysdeps/s390/s390-32/multiarch/strcpy.c
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,21 +0,0 @@
 | ||||
| -/* Multiple versions of strcpy.
 | ||||
| -   Copyright (C) 2015-2018 Free Software Foundation, Inc.
 | ||||
| -   This file is part of the GNU C Library.
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -/* This wrapper-file is needed, because otherwise file
 | ||||
| -   sysdeps/s390/s390-[32|64]/strcpy.S will be used.  */
 | ||||
| -#include <sysdeps/s390/multiarch/strcpy.c>
 | ||||
| diff --git a/sysdeps/s390/s390-32/strcpy.S b/sysdeps/s390/s390-32/strcpy.S
 | ||||
| deleted file mode 100644 | ||||
| index d49136ee92b83378..0000000000000000
 | ||||
| --- a/sysdeps/s390/s390-32/strcpy.S
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,36 +0,0 @@
 | ||||
| -/* strcpy - copy a string from source to destination. For IBM S390
 | ||||
| -   This file is part of the GNU C Library.
 | ||||
| -   Copyright (C) 2000-2018 Free Software Foundation, Inc.
 | ||||
| -   Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -/*
 | ||||
| - * R2 = address of destination
 | ||||
| - * R3 = address of source
 | ||||
| - */
 | ||||
| -
 | ||||
| -#include "sysdep.h"
 | ||||
| -#include "asm-syntax.h"
 | ||||
| -
 | ||||
| -	.text
 | ||||
| -ENTRY(strcpy)
 | ||||
| -	slr   %r0,%r0
 | ||||
| -	lr    %r1,%r2
 | ||||
| -0:      mvst  %r1,%r3
 | ||||
| -	jo    0b
 | ||||
| -	br    %r14
 | ||||
| -END(strcpy)
 | ||||
| -libc_hidden_builtin_def (strcpy)
 | ||||
| diff --git a/sysdeps/s390/s390-64/multiarch/strcpy.c b/sysdeps/s390/s390-64/multiarch/strcpy.c
 | ||||
| deleted file mode 100644 | ||||
| index 6a22e31a03c8c1c4..0000000000000000
 | ||||
| --- a/sysdeps/s390/s390-64/multiarch/strcpy.c
 | ||||
| +++ /dev/null
 | ||||
| @@ -1,21 +0,0 @@
 | ||||
| -/* Multiple versions of strcpy.
 | ||||
| -   Copyright (C) 2015-2018 Free Software Foundation, Inc.
 | ||||
| -   This file is part of the GNU C Library.
 | ||||
| -
 | ||||
| -   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| -   modify it under the terms of the GNU Lesser General Public
 | ||||
| -   License as published by the Free Software Foundation; either
 | ||||
| -   version 2.1 of the License, or (at your option) any later version.
 | ||||
| -
 | ||||
| -   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| -   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| -   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| -   Lesser General Public License for more details.
 | ||||
| -
 | ||||
| -   You should have received a copy of the GNU Lesser General Public
 | ||||
| -   License along with the GNU C Library; if not, see
 | ||||
| -   <http://www.gnu.org/licenses/>.  */
 | ||||
| -
 | ||||
| -/* This wrapper-file is needed, because otherwise file
 | ||||
| -   sysdeps/s390/s390-[32|64]/strcpy.S will be used.  */
 | ||||
| -#include <sysdeps/s390/multiarch/strcpy.c>
 | ||||
| diff --git a/sysdeps/s390/multiarch/strcpy-vx.S b/sysdeps/s390/strcpy-vx.S
 | ||||
| similarity index 85% | ||||
| rename from sysdeps/s390/multiarch/strcpy-vx.S | ||||
| rename to sysdeps/s390/strcpy-vx.S | ||||
| index 52197f57f7b5d5cf..844d23e4fee32c9b 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strcpy-vx.S
 | ||||
| +++ b/sysdeps/s390/strcpy-vx.S
 | ||||
| @@ -16,13 +16,13 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| -
 | ||||
| -# include "sysdep.h"
 | ||||
| -# include "asm-syntax.h"
 | ||||
| +#include <ifunc-strcpy.h>
 | ||||
| +#include "sysdep.h"
 | ||||
| +#include "asm-syntax.h"
 | ||||
|   | ||||
|  	.text | ||||
|   | ||||
| +#if HAVE_STRCPY_Z13
 | ||||
|  /* char * strcpy (const char *dest, const char *src) | ||||
|     Copy string src to dest. | ||||
|   | ||||
| @@ -36,7 +36,7 @@
 | ||||
|     -v17=index of zero | ||||
|     -v18=part of src | ||||
|  */ | ||||
| -ENTRY(__strcpy_vx)
 | ||||
| +ENTRY(STRCPY_Z13)
 | ||||
|  	.machine "z13" | ||||
|  	.machinemode "zarch_nohighgprs" | ||||
|   | ||||
| @@ -97,13 +97,13 @@ ENTRY(__strcpy_vx)
 | ||||
|  .Lfound_align: | ||||
|  	vstl	%v16,%r5,0(%r2)	/* Copy characters including zero.  */ | ||||
|  	br	%r14 | ||||
| -END(__strcpy_vx)
 | ||||
| +END(STRCPY_Z13)
 | ||||
|   | ||||
| -/* Use mvst-strcpy-implementation as default implementation.  */
 | ||||
| -# define strcpy __strcpy_c
 | ||||
| -# undef libc_hidden_builtin_def
 | ||||
| -# define libc_hidden_builtin_def(name) strong_alias(__strcpy_c, __GI_strcpy)
 | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +# if ! HAVE_STRCPY_IFUNC
 | ||||
| +strong_alias (STRCPY_Z13, strcpy)
 | ||||
| +# endif
 | ||||
|   | ||||
| -/* Include mvst-strcpy-implementation in s390-32/s390-64 subdirectory.  */
 | ||||
| -#include <strcpy.S>
 | ||||
| +# if ! HAVE_STRCPY_Z900_G5 && defined SHARED && IS_IN (libc)
 | ||||
| +strong_alias (STRCPY_Z13, __GI_strcpy)
 | ||||
| +# endif
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/s390-64/strcpy.S b/sysdeps/s390/strcpy-z900.S
 | ||||
| similarity index 66% | ||||
| rename from sysdeps/s390/s390-64/strcpy.S | ||||
| rename to sysdeps/s390/strcpy-z900.S | ||||
| index 203c73c905d0d86c..42798b1fd5c51187 100644
 | ||||
| --- a/sysdeps/s390/s390-64/strcpy.S
 | ||||
| +++ b/sysdeps/s390/strcpy-z900.S
 | ||||
| @@ -1,4 +1,4 @@
 | ||||
| -/* strcpy - copy a string from source to destination.  64 bit S/390 version.
 | ||||
| +/* strcpy - copy a string from source to destination.  64/31 bit S/390 version.
 | ||||
|     Copyright (C) 2001-2018 Free Software Foundation, Inc. | ||||
|     Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com). | ||||
|     This file is part of the GNU C Library. | ||||
| @@ -21,15 +21,36 @@
 | ||||
|       %r2 = address of destination | ||||
|       %r3 = address of source.  */ | ||||
|   | ||||
| +#include <ifunc-strcpy.h>
 | ||||
|  #include "sysdep.h" | ||||
|  #include "asm-syntax.h" | ||||
|   | ||||
| +#if HAVE_STRCPY_Z900_G5
 | ||||
| +# if defined __s390x__
 | ||||
| +#  define SLGR	slgr
 | ||||
| +#  define LGR	lgr
 | ||||
| +# else
 | ||||
| +#  define SLGR	slr
 | ||||
| +#  define LGR	lr
 | ||||
| +# endif /* ! defined __s390x__  */
 | ||||
| +
 | ||||
|          .text | ||||
| -ENTRY(strcpy)
 | ||||
| -	slgr  %r0,%r0
 | ||||
| -	lgr   %r1,%r2
 | ||||
| +ENTRY(STRCPY_Z900_G5)
 | ||||
| +	SLGR  %r0,%r0
 | ||||
| +	LGR   %r1,%r2
 | ||||
|  0:	mvst  %r1,%r3 | ||||
|  	jo    0b | ||||
|  	br    %r14 | ||||
| -END(strcpy)
 | ||||
| -libc_hidden_builtin_def (strcpy)
 | ||||
| +END(STRCPY_Z900_G5)
 | ||||
| +
 | ||||
| +# undef SLGR
 | ||||
| +# undef LGR
 | ||||
| +
 | ||||
| +# if ! HAVE_STRCPY_IFUNC
 | ||||
| +strong_alias (STRCPY_Z900_G5, strcpy)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if defined SHARED && IS_IN (libc)
 | ||||
| +strong_alias (STRCPY_Z900_G5, __GI_strcpy)
 | ||||
| +# endif
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/strcpy.c
 | ||||
| similarity index 69% | ||||
| rename from sysdeps/s390/multiarch/strcpy.c | ||||
| rename to sysdeps/s390/strcpy.c | ||||
| index 8f32a13f6730c427..f4e28e24c85b7162 100644
 | ||||
| --- a/sysdeps/s390/multiarch/strcpy.c
 | ||||
| +++ b/sysdeps/s390/strcpy.c
 | ||||
| @@ -16,12 +16,25 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-strcpy.h>
 | ||||
| +
 | ||||
| +#if HAVE_STRCPY_IFUNC
 | ||||
|  # define strcpy __redirect_strcpy | ||||
|  # include <string.h> | ||||
|  # undef strcpy | ||||
|  # include <ifunc-resolve.h> | ||||
|   | ||||
| -s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy)
 | ||||
| +# if HAVE_STRCPY_Z900_G5
 | ||||
| +extern __typeof (__redirect_strcpy) STRCPY_Z900_G5 attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if HAVE_STRCPY_Z13
 | ||||
| +extern __typeof (__redirect_strcpy) STRCPY_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
|   | ||||
| +s390_libc_ifunc_expr (__redirect_strcpy, strcpy,
 | ||||
| +		      (HAVE_STRCPY_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? STRCPY_Z13
 | ||||
| +		      : STRCPY_DEFAULT
 | ||||
| +		      )
 | ||||
|  #endif | ||||
							
								
								
									
										279
									
								
								SOURCES/glibc-rh1659438-19.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										279
									
								
								SOURCES/glibc-rh1659438-19.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,279 @@ | ||||
| commit 970449311ded3cacb6058c96143dd4c057900589 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:11 2018 +0100 | ||||
| 
 | ||||
|     S390: Refactor stpcpy ifunc handling. | ||||
|      | ||||
|     The ifunc handling for stpcpy is adjusted in order to omit ifunc | ||||
|     variants if those will never be used as the minimum architecture level | ||||
|     already supports newer CPUs by default. | ||||
|     Glibc internal calls will then also use the "newer" ifunc variant. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/multiarch/Makefile | ||||
|             (sysdep_routines): Remove stpcpy variants. | ||||
|             * sysdeps/s390/Makefile (sysdep_routines): Add stpcpy variants. | ||||
|             * sysdeps/s390/multiarch/ifunc-impl-list.c | ||||
|             (__libc_ifunc_impl_list): Refactor ifunc handling for stpcpy. | ||||
|             * sysdeps/s390/multiarch/stpcpy-c.c: Move to ... | ||||
|             * sysdeps/s390/stpcpy-c.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/stpcpy-vx.S: Move to ... | ||||
|             * sysdeps/s390/stpcpy-vx.S: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/multiarch/stpcpy.c: Move to ... | ||||
|             * sysdeps/s390/stpcpy.c: ... here and adjust ifunc handling. | ||||
|             * sysdeps/s390/ifunc-stpcpy.h: New file. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
 | ||||
| index e4191319531ecb01..b7e1bc8aecf2f8c9 100644
 | ||||
| --- a/sysdeps/s390/Makefile
 | ||||
| +++ b/sysdeps/s390/Makefile
 | ||||
| @@ -39,5 +39,6 @@ sysdep_routines += bzero memset memset-z900 \
 | ||||
|  		   memmem memmem-vx memmem-c \ | ||||
|  		   strlen strlen-vx strlen-c \ | ||||
|  		   strnlen strnlen-vx strnlen-c \ | ||||
| -		   strcpy strcpy-vx strcpy-z900
 | ||||
| +		   strcpy strcpy-vx strcpy-z900 \
 | ||||
| +		   stpcpy stpcpy-vx stpcpy-c
 | ||||
|  endif | ||||
| diff --git a/sysdeps/s390/ifunc-stpcpy.h b/sysdeps/s390/ifunc-stpcpy.h
 | ||||
| new file mode 100644 | ||||
| index 0000000000000000..9a70cd7c8c4f4582
 | ||||
| --- /dev/null
 | ||||
| +++ b/sysdeps/s390/ifunc-stpcpy.h
 | ||||
| @@ -0,0 +1,52 @@
 | ||||
| +/* stpcpy variant information on S/390 version.
 | ||||
| +   Copyright (C) 2018 Free Software Foundation, Inc.
 | ||||
| +   This file is part of the GNU C Library.
 | ||||
| +
 | ||||
| +   The GNU C Library is free software; you can redistribute it and/or
 | ||||
| +   modify it under the terms of the GNU Lesser General Public
 | ||||
| +   License as published by the Free Software Foundation; either
 | ||||
| +   version 2.1 of the License, or (at your option) any later version.
 | ||||
| +
 | ||||
| +   The GNU C Library is distributed in the hope that it will be useful,
 | ||||
| +   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||
| +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | ||||
| +   Lesser General Public License for more details.
 | ||||
| +
 | ||||
| +   You should have received a copy of the GNU Lesser General Public
 | ||||
| +   License along with the GNU C Library; if not, see
 | ||||
| +   <http://www.gnu.org/licenses/>.  */
 | ||||
| +
 | ||||
| +#if defined USE_MULTIARCH && IS_IN (libc)		\
 | ||||
| +  && ! defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define HAVE_STPCPY_IFUNC	1
 | ||||
| +#else
 | ||||
| +# define HAVE_STPCPY_IFUNC	0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#ifdef HAVE_S390_VX_ASM_SUPPORT
 | ||||
| +# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT HAVE_STPCPY_IFUNC
 | ||||
| +#else
 | ||||
| +# define HAVE_STPCPY_IFUNC_AND_VX_SUPPORT 0
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if defined HAVE_S390_MIN_Z13_ZARCH_ASM_SUPPORT
 | ||||
| +# define STPCPY_DEFAULT		STPCPY_Z13
 | ||||
| +# define HAVE_STPCPY_C		0
 | ||||
| +# define HAVE_STPCPY_Z13	1
 | ||||
| +#else
 | ||||
| +# define STPCPY_DEFAULT		STPCPY_C
 | ||||
| +# define HAVE_STPCPY_C		1
 | ||||
| +# define HAVE_STPCPY_Z13	HAVE_STPCPY_IFUNC_AND_VX_SUPPORT
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STPCPY_C
 | ||||
| +# define STPCPY_C		__stpcpy_c
 | ||||
| +#else
 | ||||
| +# define STPCPY_C		NULL
 | ||||
| +#endif
 | ||||
| +
 | ||||
| +#if HAVE_STPCPY_Z13
 | ||||
| +# define STPCPY_Z13		__stpcpy_vx
 | ||||
| +#else
 | ||||
| +# define STPCPY_Z13		NULL
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
 | ||||
| index 50f7f0b78df723bb..9517417dcbe1c701 100644
 | ||||
| --- a/sysdeps/s390/multiarch/Makefile
 | ||||
| +++ b/sysdeps/s390/multiarch/Makefile
 | ||||
| @@ -1,6 +1,5 @@
 | ||||
|  ifeq ($(subdir),string) | ||||
| -sysdep_routines += stpcpy stpcpy-vx stpcpy-c \
 | ||||
| -		   strncpy strncpy-vx \
 | ||||
| +sysdep_routines += strncpy strncpy-vx \
 | ||||
|  		   stpncpy stpncpy-vx stpncpy-c \ | ||||
|  		   strcat strcat-vx strcat-c \ | ||||
|  		   strncat strncat-vx strncat-c \ | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| index 1784372db9828463..678ed13833332f11 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
 | ||||
| @@ -29,6 +29,7 @@
 | ||||
|  #include <ifunc-strlen.h> | ||||
|  #include <ifunc-strnlen.h> | ||||
|  #include <ifunc-strcpy.h> | ||||
| +#include <ifunc-stpcpy.h>
 | ||||
|   | ||||
|  /* Maximum number of IFUNC implementations.  */ | ||||
|  #define MAX_IFUNC	3 | ||||
| @@ -203,6 +204,18 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|  		) | ||||
|  #endif /* HAVE_STRCPY_IFUNC  */ | ||||
|   | ||||
| +#if HAVE_STPCPY_IFUNC
 | ||||
| +    IFUNC_IMPL (i, name, stpcpy,
 | ||||
| +# if HAVE_STPCPY_Z13
 | ||||
| +		IFUNC_IMPL_ADD (array, i, stpcpy,
 | ||||
| +				dl_hwcap & HWCAP_S390_VX, STPCPY_Z13)
 | ||||
| +# endif
 | ||||
| +# if HAVE_STPCPY_C
 | ||||
| +		IFUNC_IMPL_ADD (array, i, stpcpy, 1, STPCPY_C)
 | ||||
| +# endif
 | ||||
| +		)
 | ||||
| +#endif /* HAVE_STPCPY_IFUNC  */
 | ||||
| +
 | ||||
|  #ifdef HAVE_S390_VX_ASM_SUPPORT | ||||
|   | ||||
|  # define IFUNC_VX_IMPL(FUNC)						\ | ||||
| @@ -217,7 +230,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 | ||||
|   | ||||
|    IFUNC_VX_IMPL (wcscpy); | ||||
|   | ||||
| -  IFUNC_VX_IMPL (stpcpy);
 | ||||
|    IFUNC_VX_IMPL (wcpcpy); | ||||
|   | ||||
|    IFUNC_VX_IMPL (strncpy); | ||||
| diff --git a/sysdeps/s390/multiarch/stpcpy-c.c b/sysdeps/s390/stpcpy-c.c
 | ||||
| similarity index 74% | ||||
| rename from sysdeps/s390/multiarch/stpcpy-c.c | ||||
| rename to sysdeps/s390/stpcpy-c.c | ||||
| index 4a1c3e5832c9b544..76ec88462717799c 100644
 | ||||
| --- a/sysdeps/s390/multiarch/stpcpy-c.c
 | ||||
| +++ b/sysdeps/s390/stpcpy-c.c
 | ||||
| @@ -16,20 +16,25 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| -# define STPCPY  __stpcpy_c
 | ||||
| -# undef weak_alias
 | ||||
| -# define weak_alias(a, b)
 | ||||
| -# ifdef SHARED
 | ||||
| -#  undef libc_hidden_def
 | ||||
| -#  define libc_hidden_def(name)					\
 | ||||
| +#include <ifunc-stpcpy.h>
 | ||||
| +
 | ||||
| +#if HAVE_STPCPY_C
 | ||||
| +# if HAVE_STPCPY_IFUNC
 | ||||
| +#  define STPCPY STPCPY_C
 | ||||
| +
 | ||||
| +#  undef weak_alias
 | ||||
| +#  define weak_alias(a, b)
 | ||||
| +
 | ||||
| +#  if defined SHARED && IS_IN (libc)
 | ||||
| +#   undef libc_hidden_def
 | ||||
| +#   define libc_hidden_def(name)				\
 | ||||
|    __hidden_ver1 (__stpcpy_c, __GI___stpcpy, __stpcpy_c); | ||||
| -#  undef libc_hidden_builtin_def
 | ||||
| -#  define libc_hidden_builtin_def(name)				\
 | ||||
| +#   undef libc_hidden_builtin_def
 | ||||
| +#   define libc_hidden_builtin_def(name)			\
 | ||||
|    strong_alias (__stpcpy_c, __stpcpy_c_1);			\ | ||||
|    __hidden_ver1 (__stpcpy_c_1, __GI_stpcpy, __stpcpy_c_1); | ||||
| -# endif /* SHARED */
 | ||||
| -
 | ||||
| +#  endif
 | ||||
| +# endif
 | ||||
|   | ||||
|  # include <string/stpcpy.c> | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/stpcpy-vx.S b/sysdeps/s390/stpcpy-vx.S
 | ||||
| similarity index 90% | ||||
| rename from sysdeps/s390/multiarch/stpcpy-vx.S | ||||
| rename to sysdeps/s390/stpcpy-vx.S | ||||
| index 6c17def0fc35d60d..d2db02d0cd714d27 100644
 | ||||
| --- a/sysdeps/s390/multiarch/stpcpy-vx.S
 | ||||
| +++ b/sysdeps/s390/stpcpy-vx.S
 | ||||
| @@ -16,7 +16,9 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-stpcpy.h>
 | ||||
| +
 | ||||
| +#if HAVE_STPCPY_Z13
 | ||||
|   | ||||
|  # include "sysdep.h" | ||||
|  # include "asm-syntax.h" | ||||
| @@ -36,7 +38,7 @@
 | ||||
|     -v17=index of zero | ||||
|     -v18=part of src | ||||
|  */ | ||||
| -ENTRY(__stpcpy_vx)
 | ||||
| +ENTRY(STPCPY_Z13)
 | ||||
|  	.machine "z13" | ||||
|  	.machinemode "zarch_nohighgprs" | ||||
|   | ||||
| @@ -100,5 +102,15 @@ ENTRY(__stpcpy_vx)
 | ||||
|  	vstl	%v16,%r5,0(%r2)	/* Copy characters including zero.  */ | ||||
|  	la	%r2,0(%r5,%r2)	/* Return pointer to zero.  */ | ||||
|  	br	%r14 | ||||
| -END(__stpcpy_vx)
 | ||||
| -#endif /* HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc) */
 | ||||
| +END(STPCPY_Z13)
 | ||||
| +
 | ||||
| +# if ! HAVE_STPCPY_IFUNC
 | ||||
| +strong_alias (STPCPY_Z13, __stpcpy)
 | ||||
| +weak_alias (__stpcpy, stpcpy)
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +# if ! HAVE_STPCPY_C && defined SHARED && IS_IN (libc)
 | ||||
| +strong_alias (STPCPY_Z13, __GI_stpcpy)
 | ||||
| +strong_alias (STPCPY_Z13, __GI___stpcpy)
 | ||||
| +# endif
 | ||||
| +#endif
 | ||||
| diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/stpcpy.c
 | ||||
| similarity index 74% | ||||
| rename from sysdeps/s390/multiarch/stpcpy.c | ||||
| rename to sysdeps/s390/stpcpy.c | ||||
| index 654f9dfbef512e34..670604e2de3806b7 100644
 | ||||
| --- a/sysdeps/s390/multiarch/stpcpy.c
 | ||||
| +++ b/sysdeps/s390/stpcpy.c
 | ||||
| @@ -16,7 +16,9 @@
 | ||||
|     License along with the GNU C Library; if not, see | ||||
|     <http://www.gnu.org/licenses/>.  */ | ||||
|   | ||||
| -#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
 | ||||
| +#include <ifunc-stpcpy.h>
 | ||||
| +
 | ||||
| +#if HAVE_STPCPY_IFUNC
 | ||||
|  # define stpcpy __redirect_stpcpy | ||||
|  # define __stpcpy __redirect___stpcpy | ||||
|  /* Omit the stpcpy inline definitions because it would redefine stpcpy.  */ | ||||
| @@ -27,9 +29,18 @@
 | ||||
|  # undef __stpcpy | ||||
|  # include <ifunc-resolve.h> | ||||
|   | ||||
| -s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy);
 | ||||
| -weak_alias (__stpcpy, stpcpy)
 | ||||
| +# if HAVE_STPCPY_C
 | ||||
| +extern __typeof (__redirect_stpcpy) STPCPY_C attribute_hidden;
 | ||||
| +# endif
 | ||||
|   | ||||
| -#else
 | ||||
| -# include <string/stpcpy.c>
 | ||||
| -#endif /* !(defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)) */
 | ||||
| +# if HAVE_STPCPY_Z13
 | ||||
| +extern __typeof (__redirect_stpcpy) STPCPY_Z13 attribute_hidden;
 | ||||
| +# endif
 | ||||
| +
 | ||||
| +s390_libc_ifunc_expr (__redirect___stpcpy, __stpcpy,
 | ||||
| +		      (HAVE_STPCPY_Z13 && (hwcap & HWCAP_S390_VX))
 | ||||
| +		      ? STPCPY_Z13
 | ||||
| +		      : STPCPY_DEFAULT
 | ||||
| +		      )
 | ||||
| +weak_alias (__stpcpy, stpcpy)
 | ||||
| +#endif
 | ||||
							
								
								
									
										58
									
								
								SOURCES/glibc-rh1659438-2.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								SOURCES/glibc-rh1659438-2.patch
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,58 @@ | ||||
| commit e8023f2685c9f97e72bbe9d2a9c968e0d8438371 | ||||
| Author: Stefan Liebler <stli@linux.ibm.com> | ||||
| Date:   Tue Dec 18 13:57:03 2018 +0100 | ||||
| 
 | ||||
|     S390: Use hwcap instead of dl_hwcap in ifunc-resolvers. | ||||
|      | ||||
|     The renaming of hwcap arguments in ifunc-resolvers is needed | ||||
|     in order to prepare for further commits which refactors | ||||
|     ifunc handling for memset, memcmp, and memcpy.  Now you are able | ||||
|     to use s390_libc_ifunc_init which stores the stfle bits | ||||
|     within the expression for an ifunc-resolver generated by | ||||
|     s390_libc_ifunc_expr. | ||||
|      | ||||
|     ChangeLog: | ||||
|      | ||||
|             * sysdeps/s390/multiarch/ifunc-resolve.h | ||||
|             (s390_libc_ifunc_init, s390_libc_ifunc, | ||||
|             s390_vx_libc_ifunc2_redirected): Use hwcap instead of dl_hwcap. | ||||
| 
 | ||||
| diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
 | ||||
| index b42ed922fd27834b..b7e20abc59638251 100644
 | ||||
| --- a/sysdeps/s390/multiarch/ifunc-resolve.h
 | ||||
| +++ b/sysdeps/s390/multiarch/ifunc-resolve.h
 | ||||
| @@ -42,9 +42,9 @@
 | ||||
|  		       : : "cc"); | ||||
|  #define s390_libc_ifunc_init()						\ | ||||
|    unsigned long long stfle_bits = 0ULL;					\ | ||||
| -  if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE)			\
 | ||||
| -		     && (dl_hwcap & HWCAP_S390_ZARCH)			\
 | ||||
| -		     && (dl_hwcap & HWCAP_S390_HIGH_GPRS)))		\
 | ||||
| +  if (__glibc_likely ((hwcap & HWCAP_S390_STFLE)			\
 | ||||
| +		      && (hwcap & HWCAP_S390_ZARCH)			\
 | ||||
| +		      && (hwcap & HWCAP_S390_HIGH_GPRS)))		\
 | ||||
|      {									\ | ||||
|        S390_STORE_STFLE (stfle_bits);					\ | ||||
|      } | ||||
| @@ -61,7 +61,7 @@
 | ||||
|  	   : __glibc_likely (S390_IS_Z10 (stfle_bits))			\ | ||||
|  	     ? RESOLVERFUNC##_z10					\ | ||||
|  	     : RESOLVERFUNC##_default,					\ | ||||
| -	   unsigned long int dl_hwcap, s390_libc_ifunc_init);
 | ||||
| +	   unsigned long int hwcap, s390_libc_ifunc_init);
 | ||||
|   | ||||
|  #define s390_vx_libc_ifunc(FUNC)		\ | ||||
|    s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC) | ||||
| @@ -79,10 +79,10 @@
 | ||||
|    extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden;	\ | ||||
|    extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden;	\ | ||||
|    __ifunc (TYPE_FUNC, FUNC,						\ | ||||
| -	   (dl_hwcap & HWCAP_S390_VX)					\
 | ||||
| +	   (hwcap & HWCAP_S390_VX)					\
 | ||||
|  	   ? RESOLVERFUNC##_vx						\ | ||||
|  	   : RESOLVERFUNC##_c,						\ | ||||
| -	   unsigned long int dl_hwcap, s390_vx_libc_ifunc_init);
 | ||||
| +	   unsigned long int hwcap, s390_vx_libc_ifunc_init);
 | ||||
|   | ||||
|  #define s390_libc_ifunc_expr_init() | ||||
|  #define s390_libc_ifunc_expr(TYPE_FUNC, FUNC, EXPR)		\ | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	Block a user