about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2011-03-11 18:02:09 -0800
committerPatrick Walton <pcwalton@mimiga.net>2011-03-11 18:03:00 -0800
commitd34e1ff89e067a57921091fbdffe8c13fa38341c (patch)
tree7c3ab414d5295bd77ef48737b2c9c6771997fe0c
parenta8fbb53d643eada0264aae902adc7f6f453c53b0 (diff)
rustc: Add a binding to LLVM's object file reader. Until it's sent upstream, add an explicit "support" library for our LLVM extensions.
-rw-r--r--src/Makefile34
-rw-r--r--src/support/Object.cpp55
-rw-r--r--src/support/README3
-rw-r--r--src/support/include/llvm-c/Object.h75
4 files changed, 164 insertions, 3 deletions
diff --git a/src/Makefile b/src/Makefile
index bceef7ffc18..dc6a78a52d4 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -34,6 +34,7 @@ DSYMUTIL := true
 
 ifeq ($(CFG_OSTYPE), FreeBSD)
   CFG_RUNTIME := librustrt.so
+  CFG_SUPPORT := librustsupport.so
   CFG_STDLIB := libstd.so
   CFG_GCC_CFLAGS += -fPIC -march=i686 -I/usr/local/include
   CFG_GCC_LINK_FLAGS += -shared -fPIC -lpthread -lrt
@@ -47,6 +48,7 @@ endif
 
 ifeq ($(CFG_OSTYPE), Linux)
   CFG_RUNTIME := librustrt.so
+  CFG_SUPPORT := librustsupport.so
   CFG_STDLIB := libstd.so
   CFG_GCC_CFLAGS += -fPIC -march=i686
   CFG_GCC_LINK_FLAGS += -shared -fPIC -ldl -lpthread -lrt
@@ -60,6 +62,7 @@ endif
 
 ifeq ($(CFG_OSTYPE), Darwin)
   CFG_RUNTIME := librustrt.dylib
+  CFG_SUPPORT := librustsupport.dylib
   CFG_STDLIB := libstd.dylib
   CFG_UNIXY := 1
   CFG_GCC_LINK_FLAGS += -dynamiclib -lpthread
@@ -85,6 +88,7 @@ ifdef CFG_WINDOWSY
     CFG_NATIVE := 1
   endif
   CFG_RUNTIME := rustrt.dll
+  CFG_SUPPORT := rustsupport.dll
   CFG_STDLIB := std.dll
   CFG_EXE_SUFFIX := .exe
   CFG_BOOT := ./rustboot.exe
@@ -107,6 +111,7 @@ ifdef CFG_UNIXY
     CFG_GCC_CROSS := i586-mingw32msvc-
     CFG_BOOT_FLAGS += -t win32-x86-pe
     CFG_RUNTIME := rustrt.dll
+    CFG_SUPPORT := rustsupport.dll
     CFG_STDLIB := std.dll
     CFG_RUSTC := ./rustc.exe
     ifdef CFG_VALGRIND
@@ -179,7 +184,7 @@ endif
 ifneq ($(CFG_LLVM_CONFIG),)
   CFG_LLVM_VERSION := $(shell $(CFG_LLVM_CONFIG) --version)
   $(info cfg: found llvm-config at $(CFG_LLVM_CONFIG))
-  CFG_LLVM_ALLOWED_VERSIONS := 2.8svn 2.8 2.9svn
+  CFG_LLVM_ALLOWED_VERSIONS := 2.8svn 2.8 2.9svn 3.0svn
   ifneq ($(findstring $(CFG_LLVM_VERSION),$(CFG_LLVM_ALLOWED_VERSIONS)),)
     $(info cfg: using LLVM version $(CFG_LLVM_VERSION))
   else
@@ -193,6 +198,10 @@ ifdef CFG_LLVM_CONFIG
   LLC := "$(shell $(CFG_LLVM_CONFIG) --bindir)/llc"
   CFG_LLC_CFLAGS := -march=x86
   LLVM-DIS := "$(shell $(CFG_LLVM_CONFIG) --bindir)/llvm-dis"
+  CFG_LLVM_INCDIR := $(shell $(CFG_LLVM_CONFIG) --includedir)
+  CFG_LLVM_CXXFLAGS := $(shell $(CFG_LLVM_CONFIG) --cxxflags)
+  CFG_LLVM_LDFLAGS := $(shell $(CFG_LLVM_CONFIG) --ldflags)
+  CFG_LLVM_LIBS := $(shell $(CFG_LLVM_CONFIG) --libs)
 endif
 
 MKFILES := Makefile
@@ -301,6 +310,14 @@ RUNTIME_HDR := rt/globals.h \
 RUNTIME_INCS := -Irt/isaac -Irt/uthash
 RUNTIME_OBJS := $(RUNTIME_CS:.cpp=.o)
 
+SUPPORT_CS := support/Object.cpp
+
+SUPPORT_HDR := support/include/llvm-c/Object.h
+
+SUPPORT_INCS := -iquote $(CFG_LLVM_INCDIR)
+SUPPORT_OBJS := $(SUPPORT_CS:.cpp=.o)
+SUPPORT_LIBS := $(CFG_LLVM_LDFLAGS) $(CFG_LLVM_LIBS)
+
 STDLIB_CRATE := lib/std.rc
 STDLIB_INPUTS := $(wildcard lib/*.rc lib/*.rs lib/*/*.rs)
 COMPILER_CRATE := comp/rustc.rc
@@ -321,14 +338,24 @@ $(CFG_RUNTIME): $(RUNTIME_OBJS) $(MKFILES) $(RUNTIME_HDR)
 	@$(call CFG_ECHO, compile: $<)
 	$(CFG_QUIET)$(call CFG_LINK_C, $@) $(RUNTIME_OBJS)
 
+$(CFG_SUPPORT): $(SUPPORT_OBJS) $(MKFILES) $(SUPPORT_HDR)
+	@$(call CFG_ECHO, compile: $<)
+	$(CFG_QUIET)$(call CFG_LINK_C, $@ $(CFG_LLVM_LDFLAGS) $(CFG_LLVM_LIBS)) \
+		$(SUPPORT_OBJS)
+
 $(CFG_STDLIB): $(STDLIB_CRATE) $(CFG_BOOT) $(MKFILES)
 	@$(call CFG_ECHO, compile: $<)
 	$(BOOT) -shared -o $@ $(STDLIB_CRATE)
 
-%.o: %.cpp $(MKFILES)
+rt/%.o: rt/%.cpp $(MKFILES)
 	@$(call CFG_ECHO, compile: $<)
 	$(CFG_QUIET)$(call CFG_COMPILE_C, $@, $(RUNTIME_INCS)) $<
 
+support/%.o: support/%.cpp $(MKFILES)
+	@$(call CFG_ECHO, compile: $<)
+	$(CFG_QUIET)$(call CFG_COMPILE_C, $@, $(CFG_LLVM_CXXFLAGS) \
+		$(SUPPORT_INCS)) $<
+
 ifdef CFG_NATIVE
 $(CFG_BOOT): $(BOOT_CMXS) $(MKFILES)
 	@$(call CFG_ECHO, compile: $<)
@@ -359,7 +386,8 @@ endif
 # Main compiler targets and rules
 ######################################################################
 
-$(CFG_RUSTC): $(COMPILER_INPUTS) $(CFG_BOOT) $(CFG_RUNTIME) $(CFG_STDLIB)
+$(CFG_RUSTC): $(COMPILER_INPUTS) $(CFG_BOOT) $(CFG_RUNTIME) $(CFG_STDLIB) \
+		$(CFG_SUPPORT)
 	@$(call CFG_ECHO, compile: $<)
 	$(BOOT) -minimal -o $@ $<
 	$(CFG_QUIET)chmod 0755 $@
diff --git a/src/support/Object.cpp b/src/support/Object.cpp
new file mode 100644
index 00000000000..f390870fb33
--- /dev/null
+++ b/src/support/Object.cpp
@@ -0,0 +1,55 @@
+//===- Object.cpp - C bindings to the object file library--------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the C bindings to the file-format-independent object
+// library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Object/ObjectFile.h"
+#include "llvm-c/Object.h"
+
+using namespace llvm;
+using namespace object;
+
+LLVMObjectFileRef LLVMCreateObjectFile(const char *ObjectPath) {
+  StringRef SR(ObjectPath);
+  return wrap(ObjectFile::createObjectFile(SR));
+}
+
+void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile) {
+  delete unwrap(ObjectFile);
+}
+
+LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile) {
+  ObjectFile::section_iterator SI = unwrap(ObjectFile)->begin_sections();
+  return wrap(new ObjectFile::section_iterator(SI));
+}
+
+void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI) {
+  delete unwrap(SI);
+}
+
+void LLVMMoveToNextSection(LLVMSectionIteratorRef SI) {
+  ObjectFile::section_iterator UnwrappedSI = *unwrap(SI);
+  ++UnwrappedSI;
+}
+
+const char *LLVMGetSectionName(LLVMSectionIteratorRef SI) {
+  return (*unwrap(SI))->getName().data();
+}
+
+uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI) {
+  return (*unwrap(SI))->getSize();
+}
+
+const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI) {
+  return (*unwrap(SI))->getContents().data();
+}
+
diff --git a/src/support/README b/src/support/README
new file mode 100644
index 00000000000..31495f22c0a
--- /dev/null
+++ b/src/support/README
@@ -0,0 +1,3 @@
+This directory currently contains some LLVM support code. This will generally
+be sent upstream to LLVM in time; for now it lives here.
+
diff --git a/src/support/include/llvm-c/Object.h b/src/support/include/llvm-c/Object.h
new file mode 100644
index 00000000000..a65a2352aa0
--- /dev/null
+++ b/src/support/include/llvm-c/Object.h
@@ -0,0 +1,75 @@
+/*===-- llvm-c/Object.h - Object Lib C Iface --------------------*- C++ -*-===*/
+/*                                                                            */
+/*                     The LLVM Compiler Infrastructure                       */
+/*                                                                            */
+/* This file is distributed under the University of Illinois Open Source      */
+/* License. See LICENSE.TXT for details.                                      */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+/*                                                                            */
+/* This header declares the C interface to libLLVMObject.a, which             */
+/* implements object file reading and writing.                                */
+/*                                                                            */
+/* Many exotic languages can interoperate with C code but have a harder time  */
+/* with C++ due to name mangling. So in addition to C, this interface enables */
+/* tools written in such languages.                                           */
+/*                                                                            */
+/*===----------------------------------------------------------------------===*/
+
+#ifndef LLVM_C_OBJECT_H
+#define LLVM_C_OBJECT_H
+
+#include "llvm-c/Core.h"
+#include "llvm/Config/llvm-config.h"
+
+#ifdef __cplusplus
+#include "llvm/Object/ObjectFile.h"
+
+extern "C" {
+#endif
+
+
+typedef struct LLVMOpaqueObjectFile *LLVMObjectFileRef;
+
+typedef struct LLVMOpaqueSectionIterator *LLVMSectionIteratorRef;
+
+LLVMObjectFileRef LLVMCreateObjectFile(const char *ObjectPath);
+void LLVMDisposeObjectFile(LLVMObjectFileRef ObjectFile);
+
+LLVMSectionIteratorRef LLVMGetSections(LLVMObjectFileRef ObjectFile);
+void LLVMDisposeSectionIterator(LLVMSectionIteratorRef SI);
+void LLVMMoveToNextSection(LLVMSectionIteratorRef SI);
+const char *LLVMGetSectionName(LLVMSectionIteratorRef SI);
+uint64_t LLVMGetSectionSize(LLVMSectionIteratorRef SI);
+const char *LLVMGetSectionContents(LLVMSectionIteratorRef SI);
+
+
+#ifdef __cplusplus
+}
+
+namespace llvm {
+  namespace object {
+    inline ObjectFile *unwrap(LLVMObjectFileRef OF) {
+      return reinterpret_cast<ObjectFile*>(OF);
+    }
+
+    inline LLVMObjectFileRef wrap(const ObjectFile *OF) {
+      return reinterpret_cast<LLVMObjectFileRef>(const_cast<ObjectFile*>(OF));
+    }
+
+    inline ObjectFile::section_iterator *unwrap(LLVMSectionIteratorRef SI) {
+      return reinterpret_cast<ObjectFile::section_iterator*>(SI);
+    }
+
+    inline LLVMSectionIteratorRef
+    wrap(const ObjectFile::section_iterator *SI) {
+      return reinterpret_cast<LLVMSectionIteratorRef>
+        (const_cast<ObjectFile::section_iterator*>(SI));
+    }
+  }
+}
+
+#endif /* defined(__cplusplus) */
+
+#endif
+