Skip to content

Commit 579671d

Browse files
committed
Modify header of object file generated by the LLVM backend to match the target architecture
1 parent cae8858 commit 579671d

File tree

2 files changed

+125
-5
lines changed

2 files changed

+125
-5
lines changed

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFMachine.java

Lines changed: 117 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,17 @@ Class<? extends Enum<? extends RelocationMethod>> relocationTypes() {
4444
Class<? extends Enum<? extends RelocationMethod>> relocationTypes() {
4545
return ELFAArch64Relocation.class;
4646
}
47+
},
48+
RISCV64 {
49+
@Override
50+
Class<? extends Enum<? extends RelocationMethod>> relocationTypes() {
51+
return ELFRISCV64Relocation.class;
52+
}
4753
};
4854

55+
private static final int NO_FLAGS = 0;
56+
private static final int RVC_DOUBLE_FLOAT_ABI = 5;
57+
4958
abstract Class<? extends Enum<? extends RelocationMethod>> relocationTypes();
5059

5160
public static ELFMachine from(String s) {
@@ -56,6 +65,8 @@ public static ELFMachine from(String s) {
5665
case "arm64":
5766
case "aarch64":
5867
return AArch64;
68+
case "riscv64":
69+
return RISCV64;
5970
}
6071
throw new IllegalStateException("unknown CPU type: " + s);
6172
}
@@ -129,6 +140,14 @@ public static ELFRelocationMethod getRelocation(ELFMachine m, RelocationKind k)
129140
throw new IllegalArgumentException("cannot map unknown relocation kind to an ELF aarch64 relocation type: " + k);
130141

131142
}
143+
case RISCV64:
144+
switch (k) {
145+
case DIRECT_8:
146+
return ELFRISCV64Relocation.R_RISCV_64;
147+
default:
148+
case UNKNOWN:
149+
throw new IllegalArgumentException("cannot map unknown relocation kind to an ELF riscv64 relocation type: " + k);
150+
}
132151
default:
133152
throw new IllegalStateException("unknown ELF machine type");
134153
}
@@ -141,6 +160,8 @@ public static ELFMachine from(int m) {
141160
return X86_64;
142161
case 0xB7:
143162
return AArch64;
163+
case 0xF3:
164+
return RISCV64;
144165
default:
145166
throw new IllegalStateException("unknown ELF machine type");
146167
}
@@ -151,6 +172,8 @@ public short toShort() {
151172
return 0xB7;
152173
} else if (this == X86_64) {
153174
return 0x3E;
175+
} else if (this == RISCV64) {
176+
return 0xF3;
154177
} else {
155178
throw new IllegalStateException("should not reach here");
156179
}
@@ -159,10 +182,34 @@ public short toShort() {
159182
public static ELFMachine getSystemNativeValue() {
160183
if (System.getProperty("os.arch").equals("aarch64")) {
161184
return AArch64;
185+
} else if (System.getProperty("os.arch").equals("riscv64")) {
186+
return RISCV64;
162187
} else {
163188
return X86_64;
164189
}
165190
}
191+
192+
public int flags() {
193+
if (this == AArch64) {
194+
/*
195+
* e_flags are always 0 for AArch64
196+
*/
197+
return NO_FLAGS;
198+
} else if (this == X86_64) {
199+
/*
200+
* e_flags are always 0 for X86
201+
*/
202+
return NO_FLAGS;
203+
} else if (this == RISCV64) {
204+
/*
205+
* Since we use the most powerful rv64gc model variant, we need to set e_flags to 5,
206+
* which are RVC and double-float ABI.
207+
*/
208+
return RVC_DOUBLE_FLOAT_ABI;
209+
} else {
210+
throw new IllegalStateException("should not reach here");
211+
}
212+
}
166213
}
167214

168215
enum ELFX86_64Relocation implements ELFRelocationMethod {
@@ -360,3 +407,72 @@ public long toLong() {
360407
return code;
361408
}
362409
}
410+
411+
enum ELFRISCV64Relocation implements ELFRelocationMethod {
412+
R_RISCV_NONE(0),
413+
R_RISCV_32(1),
414+
R_RISCV_64(2),
415+
R_RISCV_RELATIVE(3),
416+
R_RISCV_COPY(4),
417+
R_RISCV_JUMP_SLOT(5),
418+
R_RISCV_TLS_DTPMOD32(6),
419+
R_RISCV_TLS_DTPMOD64(7),
420+
R_RISCV_TLS_DTPREL32(8),
421+
R_RISCV_TLS_DTPREL64(9),
422+
R_RISCV_TLS_TPREL32(10),
423+
R_RISCV_TLS_TPREL64(11),
424+
R_RISCV_BRANCH(16),
425+
R_RISCV_JAL(17),
426+
R_RISCV_CALL(18),
427+
R_RISCV_CALL_PLT(19),
428+
R_RISCV_GOT_HI20(20),
429+
R_RISCV_TLS_GOT_HI20(21),
430+
R_RISCV_TLS_GD_HI20(22),
431+
R_RISCV_PCREL_HI20(23),
432+
R_RISCV_PCREL_LO12_I(24),
433+
R_RISCV_PCREL_LO12_S(25),
434+
R_RISCV_HI20(26),
435+
R_RISCV_LO12_I(27),
436+
R_RISCV_LO12_S(28),
437+
R_RISCV_TPREL_HI20(29),
438+
R_RISCV_TPREL_LO12_I(30),
439+
R_RISCV_TPREL_LO12_S(31),
440+
R_RISCV_TPREL_ADD(32),
441+
R_RISCV_ADD8(33),
442+
R_RISCV_ADD16(34),
443+
R_RISCV_ADD32(35),
444+
R_RISCV_ADD64(36),
445+
R_RISCV_SUB8(37),
446+
R_RISCV_SUB16(38),
447+
R_RISCV_SUB32(39),
448+
R_RISCV_SUB64(40),
449+
R_RISCV_GNU_VTINHERIT(41),
450+
R_RISCV_GNU_VTENTRY(42),
451+
R_RISCV_ALIGN(43),
452+
R_RISCV_RVC_BRANCH(44),
453+
R_RISCV_RVC_JUMP(45),
454+
R_RISCV_RVC_LUI(46),
455+
R_RISCV_GPREL_I(47),
456+
R_RISCV_GPREL_S(48),
457+
R_RISCV_TPREL_I(49),
458+
R_RISCV_TPREL_S(50),
459+
R_RISCV_RELAX(51),
460+
R_RISCV_SUB6(52),
461+
R_RISCV_SET6(53),
462+
R_RISCV_SET8(54),
463+
R_RISCV_SET16(55),
464+
R_RISCV_SET32(56),
465+
R_RISCV_32_PCREL(57),
466+
R_RISCV_NUM(58);
467+
468+
private final long code;
469+
470+
ELFRISCV64Relocation(long code) {
471+
this.code = code;
472+
}
473+
474+
@Override
475+
public long toLong() {
476+
return code;
477+
}
478+
}

substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/elf/ELFObjectFile.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ public class ELFObjectFile extends ObjectFile {
8181
private char abiVersion;
8282
private ELFClass fileClass = ELFClass.getSystemNativeValue();
8383
private ELFMachine machine;
84-
private long processorSpecificFlags; // FIXME: to encapsulate (EF_* in elf.h)
84+
private long processorFlags; // FIXME: to encapsulate (EF_* in elf.h)
8585
private final boolean runtimeDebugInfoGeneration;
8686

8787
private ELFObjectFile(int pageSize, ELFMachine machine, boolean runtimeDebugInfoGeneration) {
8888
super(pageSize);
8989
this.runtimeDebugInfoGeneration = runtimeDebugInfoGeneration;
9090
// Create the elements of an empty ELF file:
9191
// 1. create header
92-
header = new ELFHeader("ELFHeader");
92+
header = new ELFHeader("ELFHeader", machine.flags());
9393
this.machine = machine;
9494
// 2. create shstrtab
9595
shstrtab = new SectionHeaderStrtab();
@@ -584,9 +584,13 @@ public int getWrittenSize() {
584584
}
585585

586586
public ELFHeader(String name) { // create an "empty" default ELF header
587+
this(name, 0);
588+
}
589+
590+
public ELFHeader(String name, int processorFlags) { // create an "empty" default ELF header
587591
super(name);
588592
ELFObjectFile.this.version = 1;
589-
ELFObjectFile.this.processorSpecificFlags = 0;
593+
ELFObjectFile.this.processorFlags = processorFlags;
590594
}
591595

592596
@Override
@@ -1129,7 +1133,7 @@ public void setMachine(ELFMachine machine) {
11291133
}
11301134

11311135
public long getFlags() {
1132-
return processorSpecificFlags;
1136+
return processorFlags;
11331137
}
11341138

11351139
@SuppressWarnings("unused")

0 commit comments

Comments
 (0)