Skip to content

Commit 0331032

Browse files
committed
Add abi flag
1 parent b83b405 commit 0331032

File tree

6 files changed

+76
-31
lines changed

6 files changed

+76
-31
lines changed

CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cmake_minimum_required(VERSION 3.10)
22

33
# set the project name
4-
project(mrc VERSION 1.3.2)
4+
project(mrc VERSION 1.3.3)
55

66
enable_testing()
77

@@ -69,3 +69,5 @@ else()
6969
install(FILES mrc-config.cmake DESTINATION share/mrc/cmake)
7070
install(FILES mrc.1 DESTINATION share/man/man1)
7171
endif()
72+
73+
install(DIRECTORY example DESTINATION share/doc/mrc/)

changelog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
Version 1.3.3
2+
- Add the ABI flag to specify ABI OS version in ELF headers
3+
14
Version 1.3.2
25
- Fix install rules in CMakeLists.txt
36
- Added example code

example/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ project(mrc-user VERSION 1.0.0 LANGUAGES CXX)
66
# Locate the mrc executable and load the mrc_* functions
77
find_package(mrc)
88

9+
# resources depend on C++17 features, like std::filesystem
10+
set(CXX_EXTENSIONS OFF)
11+
set(CMAKE_CXX_STANDARD 17)
12+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
13+
914
# Write out an mrsrc.hpp file and make sure the compiler finds it
1015
mrc_write_header(${CMAKE_CURRENT_BINARY_DIR}/mrsrc.hpp)
1116
include_directories(${CMAKE_CURRENT_BINARY_DIR})

mrc-manual.pdf

546 Bytes
Binary file not shown.

mrc.1

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mrc [\fB-o\fR|\fB--output\fR outputfile]
1010
[\fB--elf-machine\fR arg]
1111
[\fB--elf-class\fR arg]
1212
[\fB--elf-data\fR arg]
13+
[\fB--elf-abi\fR arg]
1314
[\fB--elf-flags\fR arg]
1415
file1 [file2...]
1516
.sp
@@ -71,6 +72,11 @@ The ELF class to use, should be either \fI1\fR for 32-bit objects or
7172
The ELF data endianness to use, should be either \fI1\fR for little-endian
7273
(=LSB) objects or \fI2\fR for big-endian (=MSB) objects.
7374
.TP
75+
\fB--elf-abi\fR number
76+
The ELF OS ABI flag to use, the exact value for this flag should be looked
77+
up in \fIelf.h\fR. Default is to use the value for the current architecture.
78+
(Value of 3 is for Linux, 9 is for FreeBSD).
79+
.TP
7480
\fB--elf-flags\fR number
7581
A value to store in the \fIe_flags\fR field of the ELF header. This can
7682
contain the EABI version for ARM e.g.

mrc.cpp

Lines changed: 59 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ struct MObjectFileImp
105105

106106
virtual void Write(std::ofstream &inFile) = 0;
107107

108-
static MObjectFileImp *Create(int machine, int elf_class, int elf_data, int flags);
108+
static MObjectFileImp *Create(int machine, int elf_class, int elf_data, int elf_abi, int flags);
109109

110110
protected:
111111
friend class MObjectFile;
@@ -290,14 +290,16 @@ struct MELFObjectFileImp : public MObjectFileImp
290290

291291
virtual void Write(std::ofstream &inFile) override;
292292

293-
MELFObjectFileImp(int machine, int flags)
293+
MELFObjectFileImp(int machine, uint8_t elf_abi, int flags)
294294
: MObjectFileImp()
295295
, mMachine(machine)
296+
, mABI(elf_abi)
296297
, mFlags(flags)
297298
{
298299
}
299300

300301
Elf_Half mMachine;
302+
uint8_t mABI;
301303
Elf_Word mFlags;
302304
};
303305

@@ -331,7 +333,7 @@ void MELFObjectFileImp<ELF_CLASS, ELF_DATA>::Write(std::ofstream &f)
331333
Elf_Ehdr eh = {
332334
// e_ident
333335
{ELFMAG0, ELFMAG1, ELFMAG2, ELFMAG3,
334-
ELF_CLASS, ELF_DATA, EV_CURRENT},
336+
ELF_CLASS, ELF_DATA, EV_CURRENT, mABI},
335337
ET_REL, // e_type
336338
mMachine, // e_machine
337339
EV_CURRENT, // e_version
@@ -772,18 +774,18 @@ void MCOFFObjectFileImp::Write(std::ofstream &f)
772774
// --------------------------------------------------------------------
773775

774776
#if __has_include(<elf.h>)
775-
MObjectFileImp *MObjectFileImp::Create(int machine, int elf_class, int elf_data, int flags)
777+
MObjectFileImp *MObjectFileImp::Create(int machine, int elf_class, int elf_data, int elf_abi, int flags)
776778
{
777779
MObjectFileImp *result = nullptr;
778780

779781
if (elf_class == ELFCLASS32 and elf_data == ELFDATA2LSB)
780-
result = new MELFObjectFileImp<ELFCLASS32, ELFDATA2LSB>(machine, flags);
782+
result = new MELFObjectFileImp<ELFCLASS32, ELFDATA2LSB>(machine, elf_abi, flags);
781783
else if (elf_class == ELFCLASS32 and elf_data == ELFDATA2MSB)
782-
result = new MELFObjectFileImp<ELFCLASS32, ELFDATA2MSB>(machine, flags);
784+
result = new MELFObjectFileImp<ELFCLASS32, ELFDATA2MSB>(machine, elf_abi, flags);
783785
else if (elf_class == ELFCLASS64 and elf_data == ELFDATA2LSB)
784-
result = new MELFObjectFileImp<ELFCLASS64, ELFDATA2LSB>(machine, flags);
786+
result = new MELFObjectFileImp<ELFCLASS64, ELFDATA2LSB>(machine, elf_abi, flags);
785787
else if (elf_class == ELFCLASS64 and elf_data == ELFDATA2MSB)
786-
result = new MELFObjectFileImp<ELFCLASS64, ELFDATA2MSB>(machine, flags);
788+
result = new MELFObjectFileImp<ELFCLASS64, ELFDATA2MSB>(machine, elf_abi, flags);
787789
else
788790
{
789791
std::cerr << "Unsupported ELF class and/or data" << std::endl;
@@ -800,8 +802,8 @@ class MObjectFile
800802
{
801803
public:
802804
#if __has_include(<elf.h>)
803-
MObjectFile(int machine, int elf_class, int elf_data, int flags)
804-
: mImpl(MObjectFileImp::Create(machine, elf_class, elf_data, flags))
805+
MObjectFile(int machine, int elf_class, int elf_data, int elf_abi, int flags)
806+
: mImpl(MObjectFileImp::Create(machine, elf_class, elf_data, elf_abi, flags))
805807
{
806808
}
807809
#endif
@@ -1005,6 +1007,7 @@ int main(int argc, char *argv[])
10051007
( "elf-machine", po::value<int>(), "The ELF machine type to use, default is same as this machine. Use one of the values from elf.h" )
10061008
( "elf-class", po::value<int>(), "ELF class, default is same as this machine. Acceptable values are 1 (32bit) and 2 (64bit)." )
10071009
( "elf-data", po::value<int>(), "ELF endianness, default is same as this machine. Acceptable values are 1 (little-endian, LSB) and 2 (big-endian, MSB)." )
1010+
( "elf-abi", po::value<int>(), "ELF OS ABI value, see file elf.h for values (linux = 3, freebsd = 9)" )
10081011
( "elf-flags", po::value<int>(), "Processor specific flags in the ELF header, e.g. the EABI version for ARM" )
10091012
#endif
10101013

@@ -1068,7 +1071,13 @@ int main(int argc, char *argv[])
10681071
// --------------------------------------------------------------------
10691072
// find out the native format. Simply look at how we were assembled ourselves
10701073

1071-
int elf_machine = EM_NONE, elf_class = 0, elf_data = 0, elf_flags = 0;
1074+
int elf_machine = EM_NONE, elf_class = 0, elf_data = 0, elf_flags = 0, elf_abi = ELFOSABI_NONE;
1075+
1076+
#if __linux or __linux__
1077+
elf_abi = ELFOSABI_LINUX;
1078+
#elif __FreeBSD__
1079+
elf_abi = ELFOSABI_FREEBSD;
1080+
#endif
10721081

10731082
#if not defined(_MSC_VER)
10741083
char exePath[PATH_MAX + 1];
@@ -1090,6 +1099,8 @@ int main(int argc, char *argv[])
10901099

10911100
elf_class = e_ident[EI_CLASS];
10921101
elf_data = e_ident[EI_DATA];
1102+
if (e_ident[EI_ABIVERSION])
1103+
elf_abi = e_ident[EI_ABIVERSION];
10931104

10941105
lseek(fd, 0, SEEK_SET);
10951106

@@ -1136,42 +1147,60 @@ int main(int argc, char *argv[])
11361147
if (not file.is_open())
11371148
throw std::runtime_error("Could not open output file for writing");
11381149

1150+
COFF_Machine win_machine = {};
1151+
#if defined(_MSC_VER)
1152+
#if defined(_M_AMD64)
1153+
machine = IMAGE_FILE_MACHINE_AMD64;
1154+
#elif defined(_M_ARM64)
1155+
machine = IMAGE_FILE_MACHINE_ARM64;
1156+
#elif defined(_M_IX86)
1157+
machine = IMAGE_FILE_MACHINE_I386;
1158+
#endif
1159+
#endif
1160+
11391161
if (vm.count("coff"))
11401162
{
1141-
COFF_Machine machine;
11421163
if (vm["coff"].as<std::string>() == "x64")
1143-
machine = IMAGE_FILE_MACHINE_AMD64;
1164+
win_machine = IMAGE_FILE_MACHINE_AMD64;
11441165
else if (vm["coff"].as<std::string>() == "arm64")
1145-
machine = IMAGE_FILE_MACHINE_ARM64;
1166+
win_machine = IMAGE_FILE_MACHINE_ARM64;
11461167
else if (vm["coff"].as<std::string>() == "x86")
1147-
machine = IMAGE_FILE_MACHINE_I386;
1168+
win_machine = IMAGE_FILE_MACHINE_I386;
11481169
else
11491170
throw std::runtime_error("Unsupported machine for COFF: " + vm["coff"].as<std::string>());
1171+
}
1172+
1173+
bool target_elf = vm.count("elf-machine") and vm.count("elf-class") and vm.count("elf-data") and vm.count("elf-flags");
1174+
if (vm.count("elf-machine"))
1175+
elf_machine = vm["elf-machine"].as<int>();
1176+
1177+
if (vm.count("elf-class"))
1178+
elf_class = vm["elf-class"].as<int>();
1179+
1180+
if (vm.count("elf-data"))
1181+
elf_data = vm["elf-data"].as<int>();
11501182

1151-
MObjectFile obj(machine);
1183+
if (vm.count("elf-abi"))
1184+
elf_abi = vm["elf-abi"].as<int>();
1185+
1186+
if (vm.count("elf-flags"))
1187+
elf_flags = vm["elf-flags"].as<int>();
1188+
1189+
if (win_machine and not target_elf)
1190+
{
1191+
MObjectFile obj(win_machine);
11521192
rsrcFile.Write(obj);
11531193
obj.Write(file);
11541194
}
11551195
#if __has_include(<elf.h>)
11561196
else
11571197
{
1158-
if (vm.count("elf-machine"))
1159-
elf_machine = vm["elf-machine"].as<int>();
1160-
1161-
if (vm.count("elf-class"))
1162-
elf_class = vm["elf-class"].as<int>();
1163-
1164-
if (vm.count("elf-data"))
1165-
elf_data = vm["elf-data"].as<int>();
1166-
1167-
if (vm.count("elf-flags"))
1168-
elf_flags = vm["elf-flags"].as<int>();
1169-
1170-
1171-
MObjectFile obj(elf_machine, elf_class, elf_data, elf_flags);
1198+
MObjectFile obj(elf_machine, elf_class, elf_data, elf_abi, elf_flags);
11721199
rsrcFile.Write(obj);
11731200
obj.Write(file);
11741201
}
1202+
#else
1203+
throw std::runtime_error("Could not create resource file, probably you're trying to create a ELF resource file on Windows?");
11751204
#endif
11761205
}
11771206
catch (const std::exception &ex)

0 commit comments

Comments
 (0)