@@ -86,6 +86,20 @@ static bool hasAllowedPrefix(const std::string & s, const std::vector<std::strin
8686 return std::any_of (allowedPrefixes.begin (), allowedPrefixes.end (), [&](const std::string & i) { return !s.compare (0 , i.size (), i); });
8787}
8888
89+ static std::string trim (std::string s)
90+ {
91+ s.erase (s.begin (), std::find_if (s.begin (), s.end (), [](unsigned char ch) { return !std::isspace (ch); }));
92+ s.erase (std::find_if (s.rbegin (), s.rend (), [](unsigned char ch) { return !std::isspace (ch); }).base (), s.end ());
93+
94+ return s;
95+ }
96+
97+ static std::string downcase (std::string s)
98+ {
99+ std::transform (s.begin (), s.end (), s.begin (), [](unsigned char c){ return std::tolower (c); });
100+ return s;
101+ }
102+
89103/* !!! G++ creates broken code if this function is inlined, don't know
90104 why... */
91105template <ElfFileParams>
@@ -1104,6 +1118,68 @@ std::string ElfFile<ElfFileParamNames>::getInterpreter()
11041118 return std::string ((char *) fileContents->data () + rdi (shdr.sh_offset ), rdi (shdr.sh_size ) - 1 );
11051119}
11061120
1121+ template <ElfFileParams>
1122+ void ElfFile<ElfFileParamNames>::modifyOsAbi(osAbiMode op, const std::string & newOsAbi)
1123+ {
1124+ if (rdi (hdr ()->e_type ) != ET_EXEC && rdi (hdr ()->e_type ) != ET_DYN) {
1125+ debug (" this is not an executable and not a dynamic library\n " );
1126+ return ;
1127+ }
1128+
1129+ unsigned char abi = hdr ()->e_ident [EI_OSABI];
1130+
1131+ if (op == printOsAbi) {
1132+ switch (abi) {
1133+ case 0 : printf (" System V\n " ); break ;
1134+ case 1 : printf (" HP-UX\n " ); break ;
1135+ case 2 : printf (" NetBSD\n " ); break ;
1136+ case 3 : printf (" Linux\n " ); break ;
1137+ case 4 : printf (" GNU Hurd\n " ); break ;
1138+ case 6 : printf (" Solaris\n " ); break ;
1139+ case 7 : printf (" AIX\n " ); break ;
1140+ case 8 : printf (" IRIX\n " ); break ;
1141+ case 9 : printf (" FreeBSD\n " ); break ;
1142+ case 10 : printf (" Tru64\n " ); break ;
1143+ case 12 : printf (" OpenBSD\n " ); break ;
1144+ case 13 : printf (" OpenVMS\n " ); break ;
1145+ default : printf (" 0x%02X\n " , (unsigned int ) abi);
1146+ }
1147+ return ;
1148+ }
1149+
1150+ unsigned char newAbi;
1151+ std::string nabi = downcase (trim (newOsAbi));
1152+ if (nabi == " system v" || nabi == " system-v" || nabi == " sysv" )
1153+ newAbi = 0 ;
1154+ else if (nabi == " hp-ux" )
1155+ newAbi = 1 ;
1156+ else if (nabi == " netbsd" )
1157+ newAbi = 2 ;
1158+ else if (nabi == " linux" || nabi == " gnu" )
1159+ newAbi = 3 ;
1160+ else if (nabi == " gnu hurd" || nabi == " gnu-hurd" || nabi == " hurd" )
1161+ newAbi = 4 ;
1162+ else if (nabi == " solaris" )
1163+ newAbi = 6 ;
1164+ else if (nabi == " aix" )
1165+ newAbi = 7 ;
1166+ else if (nabi == " irix" )
1167+ newAbi = 8 ;
1168+ else if (nabi == " freebsd" )
1169+ newAbi = 9 ;
1170+ else if (nabi == " tru64" )
1171+ newAbi = 10 ;
1172+ else if (nabi == " openbsd" )
1173+ newAbi = 12 ;
1174+ else if (nabi == " openvms" )
1175+ newAbi = 13 ;
1176+ else
1177+ error (" unrecognized OS ABI" );
1178+
1179+ hdr ()->e_ident [EI_OSABI] = newAbi;
1180+ changed = true ;
1181+ }
1182+
11071183template <ElfFileParams>
11081184void ElfFile<ElfFileParamNames>::modifySoname(sonameMode op, const std::string & newSoname)
11091185{
@@ -1739,6 +1815,9 @@ void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string>
17391815}
17401816
17411817static bool printInterpreter = false ;
1818+ static bool printOsAbi = false ;
1819+ static bool setOsAbi = false ;
1820+ static std::string newOsAbi;
17421821static bool printSoname = false ;
17431822static bool setSoname = false ;
17441823static std::string newSoname;
@@ -1764,6 +1843,12 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con
17641843 if (printInterpreter)
17651844 printf (" %s\n " , elfFile.getInterpreter ().c_str ());
17661845
1846+ if (printOsAbi)
1847+ elfFile.modifyOsAbi (elfFile.printOsAbi , " " );
1848+
1849+ if (setOsAbi)
1850+ elfFile.modifyOsAbi (elfFile.replaceOsAbi , newOsAbi);
1851+
17671852 if (printSoname)
17681853 elfFile.modifySoname (elfFile.printSoname , " " );
17691854
@@ -1839,6 +1924,8 @@ void showHelp(const std::string & progName)
18391924 [--set-interpreter FILENAME]\n \
18401925 [--page-size SIZE]\n \
18411926 [--print-interpreter]\n \
1927+ [--print-os-abi]\t\t Prints 'EI_OSABI' field of ELF header\n \
1928+ [--set-os-abi ABI]\t\t Sets 'EI_OSABI' field of ELF header to ABI.\n \
18421929 [--print-soname]\t\t Prints 'DT_SONAME' entry of .dynamic section. Raises an error if DT_SONAME doesn't exist\n \
18431930 [--set-soname SONAME]\t\t Sets 'DT_SONAME' entry to SONAME.\n \
18441931 [--set-rpath RPATH]\n \
@@ -1888,6 +1975,14 @@ int mainWrapped(int argc, char * * argv)
18881975 else if (arg == " --print-interpreter" ) {
18891976 printInterpreter = true ;
18901977 }
1978+ else if (arg == " --print-os-abi" ) {
1979+ printOsAbi = true ;
1980+ }
1981+ else if (arg == " --set-os-abi" ) {
1982+ if (++i == argc) error (" missing argument" );
1983+ setOsAbi = true ;
1984+ newOsAbi = resolveArgument (argv[i]);
1985+ }
18911986 else if (arg == " --print-soname" ) {
18921987 printSoname = true ;
18931988 }
0 commit comments