Skip to content

Commit c073def

Browse files
sbrookesarunthomas
authored andcommitted
SSITH/HOPE (also called ISP) tagging support
1 parent fa144fe commit c073def

File tree

15 files changed

+689
-19
lines changed

15 files changed

+689
-19
lines changed

llvm/include/llvm/MC/MCObjectFileInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,9 @@ class MCObjectFileInfo {
164164
/// Remarks section.
165165
MCSection *RemarksSection = nullptr;
166166

167+
// ISP Metadata Section
168+
MCSection *ISPMetadataSection;
169+
167170
/// EH frame section.
168171
///
169172
/// It is initialized on demand so it can be overwritten (with uniquing).
@@ -401,6 +404,10 @@ class MCObjectFileInfo {
401404
return EHFrameSection;
402405
}
403406

407+
MCSection *getISPMetadataSection() const {
408+
return ISPMetadataSection;
409+
}
410+
404411
enum Environment { IsMachO, IsELF, IsCOFF, IsWasm, IsXCOFF };
405412
Environment getObjectFileType() const { return Env; }
406413

llvm/include/llvm/MC/MCStreamer.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#ifndef LLVM_MC_MCSTREAMER_H
1414
#define LLVM_MC_MCSTREAMER_H
1515

16+
#include "llvm/MC/SSITHMetadata.h"
1617
#include "llvm/ADT/ArrayRef.h"
1718
#include "llvm/ADT/DenseMap.h"
1819
#include "llvm/ADT/Optional.h"
@@ -597,7 +598,7 @@ class MCStreamer {
597598
/// \param ByteAlignment - The alignment of the symbol if
598599
/// non-zero. This must be a power of 2.
599600
virtual void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
600-
unsigned ByteAlignment);
601+
unsigned ByteAlignment) = 0;
601602

602603
/// Emit a local common (.lcomm) symbol.
603604
///
@@ -618,6 +619,10 @@ class MCStreamer {
618619
uint64_t Size = 0, unsigned ByteAlignment = 0,
619620
SMLoc Loc = SMLoc()) = 0;
620621

622+
/// SSITH metadata write - only defined by MCELFStreamer
623+
virtual void EmitSSITHMetadataEntry(SmallVector<MCFixup, 4> &Fixups,
624+
uint8_t MD_type, uint8_t tag) {}
625+
621626
/// Emit a thread local bss (.tbss) symbol.
622627
///
623628
/// \param Section - The thread local common section.
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
/*
2+
* Copyright © 2017-2018 The Charles Stark Draper Laboratory, Inc. and/or Dover Microsystems, Inc.
3+
* All rights reserved.
4+
*
5+
* Use and disclosure subject to the following license.
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+
*/
26+
27+
#ifndef METADATA_H
28+
#define METADATA_H
29+
30+
#define ISP_METADATA_ELF_SECTION_NAME ".dover_metadata"
31+
32+
/* New metadata format in images:
33+
34+
The goal with this format is to establish a smaller encoding, and a somewhat more general purpose
35+
descriptive encoding. Ultimately, some of these fields will be uleb128 encoded, as soon as we
36+
can figure out some tool bugs. For now, some of the uleb128 destined fields are fixed width.
37+
We note these fields in the descriptions here for future notice.
38+
39+
Metadata operations in the image now consist of a stream, with some operations being dependent
40+
on data from previous operations. This is similar to DWARF debug information encoding. Code
41+
which processes the metadata should process the stream of operations in order, changing
42+
internal state as it goes.
43+
44+
The first operation encountered in any metadata stream sets the current base address off which
45+
subsequent operations should be based.
46+
47+
DMD_SET_BASE_ADDRESS_OP (uleb128, but currently byte)
48+
<address> (uintptr_t)
49+
50+
Following the SET_BASE_ADDRESS operation, will be a sequence of zero or more other operations.
51+
The SET_BASE_ADDRESS operation can appear multiple times. It just resets the current base
52+
address value for interpretation of operations that follow it in the stream.
53+
54+
DMD_TAG_ADDRESS_OP (uleb128, but currently byte)
55+
<relative address> (uleb128, but currently 32bits)
56+
<tag specifier> (uleb128, but currently byte)
57+
58+
The TAG_ADDRESS operation causes a tag to be applied to a specific address. The address to be
59+
tagged is formed by adding the <relative address> field to the current base address. The
60+
<tag specifier> field names the tag to be applied to the resulting address. The specifier
61+
is a known, stable constant specific to supported policies. The constant value is invariant
62+
across minor revisions and builds of the operating kernel and policy code, to allow compiled
63+
binaries to have some longevity. Tagging code will use this constant to look up the appropriate
64+
runtime tag handle or value to apply to the address.
65+
66+
DMD_TAG_ADDRESS_RANGE (uleb128, but currently byte)
67+
<relative start address> (uleb128, but currently 32bits)
68+
<relative end address> (uleb128, but currently 32bits)
69+
<tag specifier> (uleb128, but currently byte)
70+
71+
The TAG_ADDRESS_RANGE operations causes a tag to be applied to a range of addresses.
72+
The start and end address ranges are formed by taking their respective relative address
73+
fields and adding them to the current base address. The <tag specifier> field names
74+
the tag to be applied to the resulting address, as per the TAG_ADDRESS operation.
75+
76+
DMD_TAG_POLICY_SYMBOL (uleb128, but currently byte)
77+
<symbol name> (asciiz)
78+
<tag type> (uleb128, but currently 32bits)
79+
80+
DMD_TAG_POLICY_SYMBOL operations cause a symbol whose length can be determined from
81+
a symbol table (e.g. ELF symbol table) to be tagged. The <tag type> field is generated
82+
by the policy tool, and is not the same as a tag specifier. Tag types are not stable,
83+
and can and will change from build to build of policies. The symbol name is a null
84+
terminated name. These records are generated by the policy tool, exclusively.
85+
86+
DMD_TAG_POLICY_RANGE (uleb128, but currently byte)
87+
<start address> (uintptr_t)
88+
<end address> (uintptr_t)
89+
<tag type> (uleb128, but currently 32bits)
90+
91+
DMD_TAG_POLICY_RANGE operations cause an address range to be tagged. The <tag type>
92+
field is generated by the policy tool, and is not the same as a tag specifier.
93+
Tag types are not stable, and can and will change from build to build of policies.
94+
These records are generated by the policy tool, exclusively.
95+
96+
DMD_TAG_POLICY_SYMBOL_RANKED (uleb128, but currently byte)
97+
<symbol name> (asciiz)
98+
<tag category> (uleb128, but currently 32bits)
99+
<rank> (uleb128, but currently 32bits)
100+
<tag type> (uleb128, but currently 32bits)
101+
102+
DMD_TAG_POLICY_SYMBOL_RANKED operations cause a symbol whose length can be determined from
103+
a symbol table (e.g. ELF symbol table) to be tagged. The <tag type> field is generated
104+
by the policy tool, and is not the same as a tag specifier. Tag types are not stable,
105+
and can and will change from build to build of policies. The symbol name is a null
106+
terminated name. These records are generated by the policy tool, exclusively.
107+
The tag category and rank fields are used to determine overrides of tags. A tag in
108+
the same category as another with a higher rank will supercede a lower ranked tag
109+
on any given address.
110+
111+
DMD_TAG_POLICY_RANGE_RANKED (uleb128, but currently byte)
112+
<start address> (uintptr_t)
113+
<end address> (uintptr_t)
114+
<tag category> (uleb128, but currently 32bits)
115+
<rank> (uleb128, but currently 32bits)
116+
<tag type> (uleb128, but currently 32bits)
117+
118+
DMD_TAG_POLICY_RANGE_RANKED operations cause an address range to be tagged. The <tag type>
119+
field is generated by the policy tool, and is not the same as a tag specifier.
120+
Tag types are not stable, and can and will change from build to build of policies.
121+
These records are generated by the policy tool, exclusively.
122+
The tag category and rank fields are used to determine overrides of tags. A tag in
123+
the same category as another with a higher rank will supercede a lower ranked tag
124+
on any given address.
125+
*/
126+
127+
/*
128+
Meta data operations:
129+
*/
130+
#define DMD_SET_BASE_ADDRESS_OP 1u
131+
#define DMD_TAG_ADDRESS_OP 2u
132+
#define DMD_TAG_ADDRESS_RANGE_OP 3u
133+
#define DMD_TAG_POLICY_SYMBOL 4u /* deprecated? */
134+
#define DMD_TAG_POLICY_RANGE 5u /* deprecated? */
135+
#define DMD_TAG_POLICY_SYMBOL_RANKED 6u
136+
#define DMD_TAG_POLICY_RANGE_RANKED 7u
137+
#define DMD_END_BLOCK 8u
138+
#define DMD_END_BLOCK_WEAK_DECL_HACK 9u
139+
#define DMD_FUNCTION_RANGE 10u /*Followed by 32bit start and 32bit end addresses*/
140+
141+
/*
142+
Tag specifiers... also serve as offset in MCSymbol ISPMetadata flags struct.
143+
*/
144+
#define DMT_CFI3L_VALID_TGT 1u
145+
#define DMT_STACK_PROLOGUE_AUTHORITY 2u
146+
#define DMT_STACK_EPILOGUE_AUTHORITY 3u
147+
#define DMT_FPTR_STORE_AUTHORITY 4u
148+
#define DMT_BRANCH_VALID_TGT 5u
149+
#define DMT_RET_VALID_TGT 6u
150+
#define DMT_RETURN_INSTR 7u
151+
#define DMT_CALL_INSTR 8u
152+
#define DMT_BRANCH_INSTR 9u
153+
#define DMT_FPTR_CREATE_AUTHORITY 10u
154+
#define DMT_WRITE_ONCE 11u
155+
156+
//#define WriteOnceFlagVal ((0x1) << (MachineInstr::MaxFlagShift + 1))
157+
158+
#include <map>
159+
#include "llvm/CodeGen/MachineInstr.h"
160+
161+
using namespace std;
162+
using namespace llvm;
163+
164+
const std::map<int, int> MachineInstFlagToMetadata = {
165+
{MachineInstr::FnProlog, DMT_STACK_PROLOGUE_AUTHORITY},
166+
{MachineInstr::FnEpilog, DMT_STACK_EPILOGUE_AUTHORITY},
167+
{MachineInstr::FPtrStore, DMT_FPTR_STORE_AUTHORITY},
168+
{MachineInstr::FPtrCreate, DMT_FPTR_CREATE_AUTHORITY},
169+
{MachineInstr::IsReturn, DMT_RETURN_INSTR},
170+
{MachineInstr::IsCall, DMT_CALL_INSTR},
171+
{MachineInstr::IsBranch, DMT_BRANCH_INSTR},
172+
{MachineInstr::CallTarget, DMT_CFI3L_VALID_TGT},
173+
{MachineInstr::ReturnTarget, DMT_RET_VALID_TGT},
174+
{MachineInstr::BranchTarget, DMT_BRANCH_VALID_TGT}
175+
};
176+
177+
#endif

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,20 +3022,23 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock &MBB) {
30223022
emitBasicBlockLoopComments(MBB, MLI, *this);
30233023
}
30243024

3025+
// TODO: condition this on SSITH compilation
30253026
// Print the main label for the block.
3026-
if (MBB.pred_empty() ||
3027-
(isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry() &&
3028-
!MBB.hasLabelMustBeEmitted())) {
3029-
if (isVerbose()) {
3030-
// NOTE: Want this comment at start of line, don't emit with AddComment.
3031-
OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
3032-
false);
3033-
}
3034-
} else {
3035-
if (isVerbose() && MBB.hasLabelMustBeEmitted())
3036-
OutStreamer->AddComment("Label of block must be emitted");
3037-
OutStreamer->EmitLabel(MBB.getSymbol());
3038-
}
3027+
// if (MBB.pred_empty() ||
3028+
// (isBlockOnlyReachableByFallthrough(&MBB) && !MBB.isEHFuncletEntry() &&
3029+
// !MBB.hasLabelMustBeEmitted())) {
3030+
// if (isVerbose()) {
3031+
// // NOTE: Want this comment at start of line, don't emit with AddComment.
3032+
// OutStreamer->emitRawComment(" %bb." + Twine(MBB.getNumber()) + ":",
3033+
// false);
3034+
// }
3035+
// } else {
3036+
// if (isVerbose() && MBB.hasLabelMustBeEmitted())
3037+
// OutStreamer->AddComment("Label of block must be emitted");
3038+
// OutStreamer->EmitLabel(MBB.getSymbol());
3039+
// }
3040+
//SSITH - Always label basic block
3041+
OutStreamer->EmitLabel(MBB.getSymbol());
30393042
}
30403043

30413044
void AsmPrinter::EmitBasicBlockEnd(const MachineBasicBlock &MBB) {}

llvm/lib/MC/MCObjectFileInfo.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "llvm/MC/MCSectionMachO.h"
2020
#include "llvm/MC/MCSectionWasm.h"
2121
#include "llvm/MC/MCSectionXCOFF.h"
22+
#include "llvm/MC/SSITHMetadata.h"
2223

2324
using namespace llvm;
2425

@@ -489,6 +490,12 @@ void MCObjectFileInfo::initELFMCObjectFileInfo(const Triple &T, bool Large) {
489490
Ctx->getELFSection(".eh_frame", EHSectionType, EHSectionFlags);
490491

491492
StackSizesSection = Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, 0);
493+
494+
RemarksSection =
495+
Ctx->getELFSection(".remarks", ELF::SHT_PROGBITS, ELF::SHF_EXCLUDE);
496+
497+
ISPMetadataSection =
498+
Ctx->getELFSection(ISP_METADATA_ELF_SECTION_NAME, ELF::SHT_PROGBITS, 0);
492499
}
493500

494501
void MCObjectFileInfo::initCOFFMCObjectFileInfo(const Triple &T) {
@@ -837,6 +844,8 @@ void MCObjectFileInfo::InitMCObjectFileInfo(const Triple &TheTriple, bool PIC,
837844
DwarfAccelNamespaceSection = nullptr; // Used only by selected targets.
838845
DwarfAccelTypesSection = nullptr; // Used only by selected targets.
839846

847+
ISPMetadataSection = nullptr;
848+
840849
TT = TheTriple;
841850

842851
switch (TT.getObjectFormat()) {

llvm/lib/Target/RISCV/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ tablegen(LLVM RISCVGenSystemOperands.inc -gen-searchable-tables)
1717
add_public_tablegen_target(RISCVCommonTableGen)
1818

1919
add_llvm_target(RISCVCodeGen
20+
ISPAsmPrinter.cpp
21+
ISPMetadataPass.cpp
2022
RISCVAsmPrinter.cpp
2123
RISCVCallLowering.cpp
2224
RISCVExpandPseudoInsts.cpp

llvm/lib/Target/RISCV/ISP.h

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
//===-- RISCV.h - Top-level interface for RISCV -----------------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file contains the entry points for global functions defined in the LLVM
10+
// RISC-V back-end.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef LLVM_LIB_TARGET_RISCV_ISP_H
15+
#define LLVM_LIB_TARGET_RISCV_ISP_H
16+
17+
#include "llvm/MC/SSITHMetadata.h"
18+
#include "MCTargetDesc/RISCVELFStreamer.h"
19+
20+
using namespace llvm;
21+
22+
class ISPTargetELFStreamer : public RISCVTargetELFStreamer {
23+
public:
24+
ISPTargetELFStreamer(MCStreamer &S, const MCSubtargetInfo &STI);
25+
26+
virtual void emitLabel(MCSymbol *Symbol) override;
27+
virtual void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &) override;
28+
virtual void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
29+
unsigned ByteAlignment) override;
30+
31+
void EmitSSITHMetadataEntry(SmallVector<MCFixup, 4> &Fixups,
32+
uint8_t MD_type, uint8_t tag);
33+
34+
private:
35+
36+
bool ISPSecInitialized = false;
37+
38+
void EmitMCSymbolMetadata(MCSymbol *Sym);
39+
void EmitMCInstMetadata(const MCInst &Inst);
40+
41+
void EmitSSITHMetadataFnRange(MCSymbol *begin, MCSymbol *end);
42+
void EmitSSITHMetadataHeader(MCObjectStreamer &Streamer);
43+
};
44+
45+
namespace llvm {
46+
class PassRegistry;
47+
class FunctionPass;
48+
49+
FunctionPass *createRISCVISPMetadataPass();
50+
void initializeRISCVISPMetadataPass(PassRegistry &);
51+
52+
}
53+
54+
#endif

0 commit comments

Comments
 (0)