@@ -18,6 +18,8 @@ int soname_only = 0;
1818int fake_soname = 1 ;
1919int filter_soname = 1 ;
2020int require_interp = 0 ;
21+ int biarch_deps = 0 ;
22+ int multiarch_deps = 0 ;
2123
2224typedef struct elfInfo_s {
2325 Elf * elf ;
@@ -29,7 +31,8 @@ typedef struct elfInfo_s {
2931 int gotGNUHASH ;
3032 char * soname ;
3133 char * interp ;
32- const char * marker ; /* elf class marker or NULL */
34+ const char * classmarker ; /* elf class marker or NULL */
35+ const char * archmarker ; /* elf arch marker or NULL */
3336
3437 ARGV_t requires ;
3538 ARGV_t provides ;
@@ -79,9 +82,9 @@ static int skipSoname(const char *soname)
7982 return 0 ;
8083}
8184
82- static const char * mkmarker (GElf_Ehdr * ehdr )
85+ static const char * mkclassmarker (GElf_Ehdr * ehdr )
8386{
84- const char * marker = NULL ;
87+ const char * classmarker = NULL ;
8588
8689 if (ehdr -> e_ident [EI_CLASS ] == ELFCLASS64 ) {
8790 switch (ehdr -> e_machine ) {
@@ -90,11 +93,106 @@ static const char *mkmarker(GElf_Ehdr *ehdr)
9093 /* alpha doesn't traditionally have 64bit markers */
9194 break ;
9295 default :
93- marker = "(64bit)" ;
96+ classmarker = "(64bit)" ;
9497 break ;
9598 }
9699 }
97- return marker ;
100+ return classmarker ;
101+ }
102+
103+ static const char * mkarchmarker (GElf_Ehdr * ehdr )
104+ {
105+ char * archmarker = NULL ;
106+ const char * elf_machine = NULL ;
107+ const char * elf_endian = NULL ;
108+ const char * elf_bitsize = NULL ;
109+
110+ /* First the machine type... */
111+ switch (ehdr -> e_machine ) {
112+ case EM_SPARC :
113+ elf_machine = "sparc" ;
114+ break ;
115+ case EM_386 :
116+ case EM_X86_64 :
117+ elf_machine = "x86" ;
118+ break ;
119+ case EM_MIPS :
120+ elf_machine = "mips" ;
121+ break ;
122+ case EM_PPC :
123+ case EM_PPC64 :
124+ elf_machine = "ppc" ;
125+ break ;
126+ case EM_S390 :
127+ elf_machine = "s390" ;
128+ break ;
129+ case EM_ARM :
130+ if ((ehdr -> e_flags | EF_ARM_ABI_FLOAT_HARD ) == EF_ARM_ABI_FLOAT_HARD )
131+ elf_machine = "armhfp" ;
132+ if ((ehdr -> e_flags | EF_ARM_ABI_FLOAT_SOFT ) == EF_ARM_ABI_FLOAT_SOFT )
133+ elf_machine = "armsfp" ;
134+ break ;
135+ case EM_SPARCV9 :
136+ elf_machine = "sparcv9" ;
137+ break ;
138+ case EM_ALPHA :
139+ elf_machine = "alpha" ;
140+ break ;
141+ case EM_AARCH64 :
142+ elf_machine = "aarch" ;
143+ break ;
144+ case EM_RISCV :
145+ elf_machine = "riscv" ;
146+ break ;
147+ default :
148+ break ;
149+ }
150+
151+ /* Then the endianness of the CPU... */
152+ switch (ehdr -> e_ident [EI_DATA ]) {
153+ case ELFDATA2LSB :
154+ elf_endian = "le" ;
155+ break ;
156+ case ELFDATA2MSB :
157+ elf_endian = "be" ;
158+ break ;
159+ default :
160+ break ;
161+ }
162+
163+ /* Then the bit size of the CPU... */
164+ switch (ehdr -> e_ident [EI_CLASS ]) {
165+ case ELFCLASS64 :
166+ elf_bitsize = "64" ;
167+ break ;
168+ case ELFCLASS32 :
169+ elf_bitsize = "32" ;
170+ break ;
171+ default :
172+ break ;
173+ }
174+
175+ /* Finally the arch marker! */
176+ switch (ehdr -> e_machine ) {
177+ case EM_MIPS :
178+ case EM_ARM :
179+ case EM_PPC64 :
180+ rasprintf (& archmarker , "(%s%s-%s)" , elf_machine , elf_endian , elf_bitsize );
181+ break ;
182+ case EM_X86_64 :
183+ /* This handling for x32 makes me weep inside... */
184+ if (ehdr -> e_ident [EI_CLASS ] == ELFCLASS32 ) {
185+ rasprintf (& archmarker , "(%s-%s-%s)" , elf_machine , "64" , "x32" );
186+ } else {
187+ rasprintf (& archmarker , "(%s-%s)" , elf_machine , elf_bitsize );
188+ }
189+ break ;
190+ default :
191+ rasprintf (& archmarker , "(%s-%s)" , elf_machine , elf_bitsize );
192+ break ;
193+ }
194+
195+ return archmarker ;
98196}
99197
100198static void addDep (ARGV_t * deps ,
@@ -145,7 +243,10 @@ static void processVerDef(Elf_Scn *scn, GElf_Shdr *shdr, elfInfo *ei)
145243 auxoffset += aux -> vda_next ;
146244 continue ;
147245 } else if (soname && !soname_only && !skipPrivate (s )) {
148- addDep (& ei -> provides , soname , s , ei -> marker );
246+ if (multiarch_deps )
247+ addDep (& ei -> provides , soname , s , ei -> archmarker );
248+ if (biarch_deps )
249+ addDep (& ei -> provides , soname , s , ei -> classmarker );
149250 }
150251 }
151252
@@ -184,7 +285,10 @@ static void processVerNeed(Elf_Scn *scn, GElf_Shdr *shdr, elfInfo *ei)
184285 break ;
185286
186287 if (ei -> isExec && soname && !soname_only && !skipPrivate (s )) {
187- addDep (& ei -> requires , soname , s , ei -> marker );
288+ if (multiarch_deps )
289+ addDep (& ei -> requires , soname , s , ei -> archmarker );
290+ if (biarch_deps )
291+ addDep (& ei -> requires , soname , s , ei -> classmarker );
188292 }
189293 auxoffset += aux -> vna_next ;
190294 }
@@ -224,8 +328,12 @@ static void processDynamic(Elf_Scn *scn, GElf_Shdr *shdr, elfInfo *ei)
224328 case DT_NEEDED :
225329 if (ei -> isExec ) {
226330 s = elf_strptr (ei -> elf , shdr -> sh_link , dyn -> d_un .d_val );
227- if (s )
228- addDep (& ei -> requires , s , NULL , ei -> marker );
331+ if (s ) {
332+ if (multiarch_deps )
333+ addDep (& ei -> requires , s , NULL , ei -> archmarker );
334+ if (biarch_deps )
335+ addDep (& ei -> requires , s , NULL , ei -> classmarker );
336+ }
229337 }
230338 break ;
231339 }
@@ -298,7 +406,8 @@ static int processFile(const char *fn, int dtype)
298406 goto exit ;
299407
300408 if (ehdr -> e_type == ET_DYN || ehdr -> e_type == ET_EXEC ) {
301- ei -> marker = mkmarker (ehdr );
409+ ei -> archmarker = mkarchmarker (ehdr );
410+ ei -> classmarker = mkclassmarker (ehdr );
302411 ei -> isDSO = (ehdr -> e_type == ET_DYN );
303412 ei -> isExec = (st .st_mode & (S_IXUSR |S_IXGRP |S_IXOTH ));
304413
@@ -324,8 +433,12 @@ static int processFile(const char *fn, int dtype)
324433 const char * bn = strrchr (fn , '/' );
325434 ei -> soname = rstrdup (bn ? bn + 1 : fn );
326435 }
327- if (ei -> soname )
328- addDep (& ei -> provides , ei -> soname , NULL , ei -> marker );
436+ if (ei -> soname ) {
437+ if (multiarch_deps )
438+ addDep (& ei -> provides , ei -> soname , NULL , ei -> archmarker );
439+ if (biarch_deps )
440+ addDep (& ei -> provides , ei -> soname , NULL , ei -> classmarker );
441+ }
329442 }
330443
331444 /* If requested and present, add dep for interpreter (ie dynamic linker) */
@@ -366,6 +479,8 @@ int main(int argc, char *argv[])
366479 { "no-fake-soname" , 0 , POPT_ARG_VAL , & fake_soname , 0 , NULL , NULL },
367480 { "no-filter-soname" , 0 , POPT_ARG_VAL , & filter_soname , 0 , NULL , NULL },
368481 { "require-interp" , 0 , POPT_ARG_VAL , & require_interp , -1 , NULL , NULL },
482+ { "biarch-deps" , 0 , POPT_ARG_VAL , & biarch_deps , -1 , NULL , NULL },
483+ { "multiarch-deps" , 0 , POPT_ARG_VAL , & multiarch_deps , -1 , NULL , NULL },
369484 POPT_AUTOHELP
370485 POPT_TABLEEND
371486 };
@@ -394,6 +509,10 @@ int main(int argc, char *argv[])
394509 }
395510 }
396511
512+ /* In the event that neither biarch nor multiarch modes are set, fallback to biarch */
513+ if (biarch_deps == 0 && multiarch_deps == 0 )
514+ biarch_deps = 1 ;
515+
397516 poptFreeContext (optCon );
398517 return rc ;
399518}
0 commit comments