@@ -86,6 +86,20 @@ static bool hasAllowedPrefix(const std::string & s, const std::vector<std::strin
86
86
return std::any_of (allowedPrefixes.begin (), allowedPrefixes.end (), [&](const std::string & i) { return !s.compare (0 , i.size (), i); });
87
87
}
88
88
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
+
89
103
/* !!! G++ creates broken code if this function is inlined, don't know
90
104
why... */
91
105
template <ElfFileParams>
@@ -1104,6 +1118,68 @@ std::string ElfFile<ElfFileParamNames>::getInterpreter()
1104
1118
return std::string ((char *) fileContents->data () + rdi (shdr.sh_offset ), rdi (shdr.sh_size ) - 1 );
1105
1119
}
1106
1120
1121
+ template <ElfFileParams>
1122
+ void ElfFile<ElfFileParamNames>::modifyOsAbi(osAbiMode op, const std::string & newOsAbi)
1123
+ {
1124
+ unsigned char abi = hdr ()->e_ident [EI_OSABI];
1125
+
1126
+ if (op == printOsAbi) {
1127
+ switch (abi) {
1128
+ case 0 : printf (" System V\n " ); break ;
1129
+ case 1 : printf (" HP-UX\n " ); break ;
1130
+ case 2 : printf (" NetBSD\n " ); break ;
1131
+ case 3 : printf (" Linux\n " ); break ;
1132
+ case 4 : printf (" GNU Hurd\n " ); break ;
1133
+ case 6 : printf (" Solaris\n " ); break ;
1134
+ case 7 : printf (" AIX\n " ); break ;
1135
+ case 8 : printf (" IRIX\n " ); break ;
1136
+ case 9 : printf (" FreeBSD\n " ); break ;
1137
+ case 10 : printf (" Tru64\n " ); break ;
1138
+ case 12 : printf (" OpenBSD\n " ); break ;
1139
+ case 13 : printf (" OpenVMS\n " ); break ;
1140
+ default : printf (" 0x%02X\n " , (unsigned int ) abi);
1141
+ }
1142
+ return ;
1143
+ }
1144
+
1145
+ unsigned char newAbi;
1146
+ std::string nabi = downcase (trim (newOsAbi));
1147
+ if (nabi == " system v" || nabi == " system-v" || nabi == " sysv" )
1148
+ newAbi = 0 ;
1149
+ else if (nabi == " hp-ux" )
1150
+ newAbi = 1 ;
1151
+ else if (nabi == " netbsd" )
1152
+ newAbi = 2 ;
1153
+ else if (nabi == " linux" || nabi == " gnu" )
1154
+ newAbi = 3 ;
1155
+ else if (nabi == " gnu hurd" || nabi == " gnu-hurd" || nabi == " hurd" )
1156
+ newAbi = 4 ;
1157
+ else if (nabi == " solaris" )
1158
+ newAbi = 6 ;
1159
+ else if (nabi == " aix" )
1160
+ newAbi = 7 ;
1161
+ else if (nabi == " irix" )
1162
+ newAbi = 8 ;
1163
+ else if (nabi == " freebsd" )
1164
+ newAbi = 9 ;
1165
+ else if (nabi == " tru64" )
1166
+ newAbi = 10 ;
1167
+ else if (nabi == " openbsd" )
1168
+ newAbi = 12 ;
1169
+ else if (nabi == " openvms" )
1170
+ newAbi = 13 ;
1171
+ else
1172
+ error (" unrecognized OS ABI" );
1173
+
1174
+ if (newAbi == abi) {
1175
+ debug (" current and requested OS ABIs are equal\n " );
1176
+ return ;
1177
+ }
1178
+
1179
+ hdr ()->e_ident [EI_OSABI] = newAbi;
1180
+ changed = true ;
1181
+ }
1182
+
1107
1183
template <ElfFileParams>
1108
1184
void ElfFile<ElfFileParamNames>::modifySoname(sonameMode op, const std::string & newSoname)
1109
1185
{
@@ -1739,6 +1815,9 @@ void ElfFile<ElfFileParamNames>::clearSymbolVersions(const std::set<std::string>
1739
1815
}
1740
1816
1741
1817
static bool printInterpreter = false ;
1818
+ static bool printOsAbi = false ;
1819
+ static bool setOsAbi = false ;
1820
+ static std::string newOsAbi;
1742
1821
static bool printSoname = false ;
1743
1822
static bool setSoname = false ;
1744
1823
static std::string newSoname;
@@ -1764,6 +1843,12 @@ static void patchElf2(ElfFile && elfFile, const FileContents & fileContents, con
1764
1843
if (printInterpreter)
1765
1844
printf (" %s\n " , elfFile.getInterpreter ().c_str ());
1766
1845
1846
+ if (printOsAbi)
1847
+ elfFile.modifyOsAbi (elfFile.printOsAbi , " " );
1848
+
1849
+ if (setOsAbi)
1850
+ elfFile.modifyOsAbi (elfFile.replaceOsAbi , newOsAbi);
1851
+
1767
1852
if (printSoname)
1768
1853
elfFile.modifySoname (elfFile.printSoname , " " );
1769
1854
@@ -1839,6 +1924,8 @@ void showHelp(const std::string & progName)
1839
1924
[--set-interpreter FILENAME]\n \
1840
1925
[--page-size SIZE]\n \
1841
1926
[--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 \
1842
1929
[--print-soname]\t\t Prints 'DT_SONAME' entry of .dynamic section. Raises an error if DT_SONAME doesn't exist\n \
1843
1930
[--set-soname SONAME]\t\t Sets 'DT_SONAME' entry to SONAME.\n \
1844
1931
[--set-rpath RPATH]\n \
@@ -1888,6 +1975,14 @@ int mainWrapped(int argc, char * * argv)
1888
1975
else if (arg == " --print-interpreter" ) {
1889
1976
printInterpreter = true ;
1890
1977
}
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
+ }
1891
1986
else if (arg == " --print-soname" ) {
1892
1987
printSoname = true ;
1893
1988
}
0 commit comments