Skip to content

Commit 47dc18d

Browse files
authored
Merge pull request #245 from ratschance/BUGFIX-fix-ppc32-issues-with-pie-bins
BUGFIX: Fix endianness issues with PIE binaries
2 parents d2e81f0 + b04764d commit 47dc18d

File tree

4 files changed

+62
-7
lines changed

4 files changed

+62
-7
lines changed

src/patchelf.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,8 +136,8 @@ class ElfFile
136136
bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y)
137137
{
138138
// A PHDR comes before everything else.
139-
if (y.p_type == PT_PHDR) return false;
140-
if (x.p_type == PT_PHDR) return true;
139+
if (elfFile->rdi(y.p_type) == PT_PHDR) return false;
140+
if (elfFile->rdi(x.p_type) == PT_PHDR) return true;
141141

142142
// Sort non-PHDRs by address.
143143
return elfFile->rdi(x.p_paddr) < elfFile->rdi(y.p_paddr);
@@ -453,7 +453,7 @@ unsigned int ElfFile<ElfFileParamNames>::getPageSize() const
453453
// Architectures (and ABIs) can have different minimum section alignment
454454
// requirements. There is no authoritative list of these values. The
455455
// current list is extracted from GNU gold's source code (abi_pagesize).
456-
switch (hdr->e_machine) {
456+
switch (rdi(hdr->e_machine)) {
457457
case EM_SPARC:
458458
case EM_MIPS:
459459
case EM_PPC:
@@ -665,7 +665,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
665665
for (auto & i : replacedSections) {
666666
std::string sectionName = i.first;
667667
Elf_Shdr & shdr = findSection(sectionName);
668-
if (shdr.sh_type != SHT_NOBITS)
668+
if (rdi(shdr.sh_type) != SHT_NOBITS)
669669
memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
670670
}
671671

@@ -778,9 +778,9 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
778778
/* Some sections may already be replaced so account for that */
779779
unsigned int i = 1;
780780
Elf_Addr pht_size = sizeof(Elf_Ehdr) + (phdrs.size() + num_notes + 1)*sizeof(Elf_Phdr);
781-
while( shdrs[i].sh_offset <= pht_size && i < rdi(hdr->e_shnum) ) {
781+
while( rdi(shdrs[i].sh_offset) <= pht_size && i < rdi(hdr->e_shnum) ) {
782782
if (not haveReplacedSection(getSectionName(shdrs[i])))
783-
replaceSection(getSectionName(shdrs[i]), shdrs[i].sh_size);
783+
replaceSection(getSectionName(shdrs[i]), rdi(shdrs[i].sh_size));
784784
i++;
785785
}
786786

@@ -835,7 +835,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
835835
assert(curOff == startOffset + neededSpace);
836836

837837
/* Write out the updated program and section headers */
838-
rewriteHeaders(hdr->e_phoff);
838+
rewriteHeaders(rdi(hdr->e_phoff));
839839
}
840840

841841

tests/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ src_TESTS = \
2525
force-rpath.sh \
2626
plain-needed.sh \
2727
output-flag.sh \
28+
no-rpath-pie-powerpc.sh \
2829
build-id.sh
2930

3031
build_TESTS = \

tests/no-rpath-pie-powerpc.sh

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#! /bin/sh -e
2+
set -x
3+
SCRATCH=scratch/no-rpath-pie-powerpc
4+
5+
no_rpath_bin="${srcdir}/no-rpath-prebuild/no-rpath-pie-powerpc"
6+
7+
if [ ! -f $no_rpath_bin ]; then
8+
echo "no 'no-rpath' binary for '$ARCH' in '${srcdir}/no-rpath-prebuild'"
9+
exit 1
10+
fi
11+
12+
rm -rf ${SCRATCH}
13+
mkdir -p ${SCRATCH}
14+
15+
cp $no_rpath_bin ${SCRATCH}/no-rpath
16+
17+
oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
18+
if test -n "$oldRPath"; then exit 1; fi
19+
../src/patchelf \
20+
--set-interpreter "$(../src/patchelf --print-interpreter ../src/patchelf)" \
21+
--set-rpath /foo:/bar:/xxxxxxxxxxxxxxx ${SCRATCH}/no-rpath
22+
23+
newRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath)
24+
if ! echo "$newRPath" | grep -q '/foo:/bar'; then
25+
echo "incomplete RPATH"
26+
exit 1
27+
fi
28+
29+
# Tests for powerpc PIE endianness regressions
30+
readelfData=$(readelf -l ${SCRATCH}/no-rpath 2>&1)
31+
32+
if [ $(echo "$readelfData" | grep --count "PHDR") != 1 ]; then
33+
# Triggered if PHDR errors appear on stderr
34+
echo "Unexpected number of occurences of PHDR in readelf results"
35+
exit 1
36+
fi
37+
38+
virtAddr=$(echo "$readelfData" | grep "PHDR" | awk '{print $3}')
39+
if [ "$virtAddr" != "0x00000034" ]; then
40+
# Triggered if the virtual address is the incorrect endianness
41+
echo "Unexpected virt addr, expected [0x00000034] got [$virtAddr]"
42+
exit 1
43+
fi
44+
45+
echo "$readelfData" | grep "LOAD" | while read -r line ; do
46+
align=$(echo "$line" | awk '{print $NF}')
47+
if [ "$align" != "0x10000" ]; then
48+
# Triggered if the target arch was not detected properly
49+
echo "Unexpected Align for LOAD segment, expected [0x10000] got [$align]"
50+
echo "Load segment: [$line]"
51+
exit 1
52+
fi
53+
done
54+
67.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)