jaulib v1.3.0
Jau Support Library (C++, Java, ..)
TestElfReader01.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2013 Gothel Software e.K.
5 * Copyright (c) 2013 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26package jau.test.sys.elf;
27
28import java.io.BufferedOutputStream;
29import java.io.File;
30import java.io.FileOutputStream;
31import java.io.IOException;
32import java.io.OutputStream;
33import java.io.RandomAccessFile;
34import java.nio.file.FileSystems;
35import java.nio.file.Files;
36import java.nio.file.Path;
37import java.util.List;
38
39import org.jau.sys.JNILibrary;
40import org.jau.sys.PlatformProps;
41import org.jau.sys.RuntimeProps;
42import org.jau.sys.PlatformTypes.OSType;
43import org.jau.sys.elf.ElfHeaderPart1;
44import org.jau.sys.elf.ElfHeaderPart2;
45import org.jau.sys.elf.Section;
46import org.jau.sys.elf.SectionArmAttributes;
47import org.jau.sys.elf.SectionHeader;
48import org.junit.FixMethodOrder;
49import org.junit.Test;
50import org.junit.runners.MethodSorters;
51
52import jau.test.junit.util.JunitTracer;
53
54@FixMethodOrder(MethodSorters.NAME_ASCENDING)
55public class TestElfReader01 extends JunitTracer {
56 public static String GNU_LINUX_SELF_EXE = "/proc/self/exe";
57 public static String ARM_HF_EXE = "tst-exe-armhf";
58 public static String ARM_SF_EXE = "tst-exe-arm";
59 static File userFile = null;
60
61 private static boolean checkFileReadAccess(final File file) {
62 try {
63 return file.isFile() && file.canRead();
64 } catch (final Throwable t) { }
65 return false;
66 }
67 static File findJVMLib(final String libName) {
68 final ClassLoader cl = TestElfReader01.class.getClassLoader();
69 final List<String> possibleLibPaths = JNILibrary.enumerateLibraryPaths(libName,
70 true /* searchSystemPath */, true /* searchSystemPathFirst */, cl);
71 for(int i=0; i<possibleLibPaths.size(); i++) {
72 final String libPath = possibleLibPaths.get(i);
73 final File lib = new File(libPath);
74 System.err.println("XXX2 #"+i+": test "+lib);
75 if( checkFileReadAccess(lib) ) {
76 return lib;
77 }
78 System.err.println("XXX2 #"+i+": "+lib+" not readable");
79 }
80 return null;
81 }
82
83 @Test
84 public void test01GNULinuxSelfExe () throws IOException {
85 if( null == userFile ) {
86 if( OSType.LINUX == PlatformProps.OS ) {
87 /**
88 * Directly using the `/proc/self/exe` via RandomAccessFile within ElfHeaderPart1 leads to a segmentation fault
89 * when using qemu binfmt_misc for armhf or aarch64 (cross build and test)!
90 *
91 * Hence we use the resolved link's exe-file, see below - don't ask ;-)
92 *
93 final File f = new File(GNU_LINUX_SELF_EXE);
94 if( checkFileReadAccess(f) ) {
95 testElfHeaderImpl(f, false);
96 }
97 */
98 final Path exe_symlink = FileSystems.getDefault().getPath("/proc/self/exe");
99 if( Files.isSymbolicLink(exe_symlink) ) {
100 final Path exe_path = Files.readSymbolicLink(exe_symlink);
101 final File f = exe_path.toFile();
102 if( checkFileReadAccess(f) ) {
103 System.err.println("ElfFile: "+exe_symlink+" -> "+exe_path+" -> "+f);
104 testElfHeaderImpl(f, false);
105 }
106 } else {
107 System.err.println("ElfFile: "+exe_symlink+" -> NULL");
108 }
109 }
110 }
111 }
112
113 @Test
114 public void test02JavaLib () throws IOException {
115 if( null == userFile ) {
116 File jvmLib = findJVMLib("java");
117 if( null == jvmLib ) {
118 jvmLib = findJVMLib("jvm");
119 }
120 if( null != jvmLib ) {
121 testElfHeaderImpl(jvmLib, false);
122 }
123 }
124 }
125
126 @Test
127 public void test99UserFile() throws IOException {
128 if( null != userFile ) {
129 testElfHeaderImpl(userFile, false);
130 }
131 }
132
133 void testElfHeaderImpl(final File file, final boolean fileOutSections) throws IOException {
135 System.err.println("Test file "+file.getAbsolutePath());
136 final RandomAccessFile in = new RandomAccessFile(file, "r");
137 try {
138 final ElfHeaderPart1 eh1;
139 final ElfHeaderPart2 eh2;
140 try {
142 eh2 = ElfHeaderPart2.read(eh1, in);
143 } catch (final Exception e) {
144 System.err.println("Probably not an ELF file - or not in current format: (caught) "+e.getMessage());
145 e.printStackTrace();
146 return;
147 }
148 int i=0;
149 System.err.println(eh1);
150 System.err.println(eh2);
151 System.err.println("SH entsz "+eh2.raw.getE_shentsize());
152 System.err.println("SH off "+toHexString(eh2.raw.getE_shoff()));
153 System.err.println("SH strndx "+eh2.raw.getE_shstrndx());
154 System.err.println("SH num "+eh2.sht.length);
155 if( 0 < eh2.sht.length ) {
156 System.err.println("SH size "+eh2.sht[0].raw.getBuffer().limit());
157 }
158 {
159 final SectionHeader sh = eh2.getSectionHeader(SectionHeader.SHT_ARM_ATTRIBUTES);
160 boolean abiVFPArgsAcceptsVFPVariant = false;
161 if( null != sh ) {
162 final SectionArmAttributes sArmAttrs = (SectionArmAttributes) sh.readSection(in);
163 final SectionArmAttributes.Attribute abiVFPArgsAttr = sArmAttrs.get(SectionArmAttributes.Tag.ABI_VFP_args);
164 if( null != abiVFPArgsAttr ) {
165 abiVFPArgsAcceptsVFPVariant = SectionArmAttributes.abiVFPArgsAcceptsVFPVariant(abiVFPArgsAttr.getULEB128());
166 }
167 }
168 System.err.println("abiVFPArgsAcceptsVFPVariant "+abiVFPArgsAcceptsVFPVariant);
169 }
170 for(i=0; i<eh2.sht.length; i++) {
171 final SectionHeader sh = eh2.sht[i];
172 System.err.println(sh);
173 final int type = sh.getType();
174 if( SectionHeader.SHT_STRTAB == type ) {
175 dumpSection(in, sh, "SHT_STRTAB", fileOutSections);
176 } else if( SectionHeader.SHT_ARM_ATTRIBUTES == type ) {
177 dumpSection(in, sh, "SHT_ARM_ATTRIBUTES", fileOutSections);
178 }
179 }
180 } finally {
181 in.close();
182 }
183 }
184
185 static void dumpSection(final RandomAccessFile in, final SectionHeader sh, final String name, final boolean fileOut) throws IllegalArgumentException, IOException {
186 final Section s = sh.readSection(in);
187 if(fileOut) {
188 final File outFile = new File("ElfSection-"+sh.getIndex()+"-"+name);
189 final OutputStream out = new BufferedOutputStream(new FileOutputStream(outFile));
190 try {
191 out.write(s.data, s.offset, s.length);
192 } finally {
193 out.close();
194 }
195 }
196 System.err.println(name+": read "+s.length+", "+s);
197 }
198
199 public static void main(final String args[]) throws IOException {
200 for(int i=0; i<args.length; i++) {
201 if(args[i].equals("-file")) {
202 i++;
203 userFile = new File(args[i]);
204 }
205 }
206 final String tstname = TestElfReader01.class.getName();
207 org.junit.runner.JUnitCore.main(tstname);
208 }
209
210 static String toHexString(final int i) { return "0x"+Integer.toHexString(i); }
211 static String toHexString(final long i) { return "0x"+Long.toHexString(i); }
212
213}
static void main(final String args[])
Static JNI Native Libraries handler.
Definition: JNILibrary.java:47
static final List< String > enumerateLibraryPaths(final String libName, final boolean searchSystemPath, final boolean searchSystemPathFirst, final ClassLoader loader)
Given the base library names (no prefixes/suffixes) for the various platforms, enumerate the possible...
Platform Properties derived from Java properties.
static final OSType OS
Runtime platform properties derived from PlatformProps and runtime query.
short getE_shstrndx()
Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]].
Definition: Ehdr_p2.java:171
short getE_shentsize()
Getter for native field: CType['uint16_t', size [fixed true, lnx64 2], [int]].
Definition: Ehdr_p2.java:149
long getE_shoff()
Getter for native field: CType['ElfN_Off' (typedef), size [fixed false, lnx64 8], [int]].
Definition: Ehdr_p2.java:94
static ElfHeaderPart1 read(final OSType osType, final RandomAccessFile in)
Note: The input stream shall stay untouch to be able to read sections!
final SectionHeader[] sht
Public access to the SectionHeader.
static ElfHeaderPart2 read(final ElfHeaderPart1 eh1, final RandomAccessFile in)
Note: The input stream shall stay untouch to be able to read sections!
final SectionHeader getSectionHeader(final int type)
Returns the 1st occurence of matching SectionHeader type, or null if not exists.
final Ehdr_p2 raw
Public access to the raw elf header part-2 (CPU/ABI dependent read)
int getType()
Returns the type of this section.
final Shdr raw
Public access to the raw elf section header.
Section readSection(final RandomAccessFile in)
Returns the Section referenced w/ this section header.
java.nio.ByteBuffer getBuffer()
Definition: Shdr.java:61