/*
* Copyright 2012, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef BCC_RS_INFO_H
#define BCC_RS_INFO_H
#include <stdint.h>
#include <string>
#include <utility>
#include "bcc/Support/Log.h"
#include "bcc/Support/Sha1Util.h"
#include <utils/String8.h>
#include <utils/Vector.h>
namespace llvm {
class Module;
}
namespace bcc {
// Forward declarations
class FileBase;
class InputFile;
class OutputFile;
class Source;
class RSScript;
typedef llvm::Module* (*RSLinkRuntimeCallback) (bcc::RSScript *, llvm::Module *, llvm::Module *);
namespace rsinfo {
/* RS info file magic */
#define RSINFO_MAGIC "\0rsinfo\n"
/* RS info file version, encoded in 4 bytes of ASCII */
#define RSINFO_VERSION "006\0"
struct __attribute__((packed)) ListHeader {
// The offset from the beginning of the file of data
uint32_t offset;
// Number of item in the list
uint32_t count;
// Size of each item
uint8_t itemSize;
};
typedef uint32_t StringIndexTy;
/* RS info file header */
struct __attribute__((packed)) Header {
// Magic versus version
uint8_t magic[8];
uint8_t version[4];
uint8_t isThreadable;
uint8_t hasDebugInformation;
uint16_t headerSize;
uint32_t strPoolSize;
// The index in the pool of the SHA-1 checksum of the source file.
// It has a fixed-length of SHA1_DIGEST_LENGTH (=20) bytes.
StringIndexTy sourceSha1Idx;
// The index in the pool of the command used to compile this source.
StringIndexTy compileCommandLineIdx;
// The index in the pool of the build fingerprint of Android when the source was compiled.
StringIndexTy buildFingerprintIdx;
struct ListHeader pragmaList;
struct ListHeader objectSlotList;
struct ListHeader exportVarNameList;
struct ListHeader exportFuncNameList;
struct ListHeader exportForeachFuncList;
};
// Use value -1 as an invalid string index marker. No need to declare with
// 'static' modifier since 'const' variable has internal linkage by default.
const StringIndexTy gInvalidStringIndex = static_cast<StringIndexTy>(-1);
struct __attribute__((packed)) PragmaItem {
// Pragma is a key-value pair.
StringIndexTy key;
StringIndexTy value;
};
struct __attribute__((packed)) ObjectSlotItem {
uint32_t slot;
};
struct __attribute__((packed)) ExportVarNameItem {
StringIndexTy name;
};
struct __attribute__((packed)) ExportFuncNameItem {
StringIndexTy name;
};
struct __attribute__((packed)) ExportForeachFuncItem {
StringIndexTy name;
uint32_t signature;
};
// Return the human-readable name of the given rsinfo::*Item in the template
// parameter. This is for debugging and error message.
template<typename Item>
inline const char *GetItemTypeName();
template<>
inline const char *GetItemTypeName<PragmaItem>()
{ return "rs pragma"; }
template<>
inline const char *GetItemTypeName<ObjectSlotItem>()
{ return "rs object slot"; }
template<>
inline const char *GetItemTypeName<ExportVarNameItem>()
{ return "rs export var"; }
template<>
inline const char *GetItemTypeName<ExportFuncNameItem>()
{ return "rs export func"; }
template<>
inline const char *GetItemTypeName<ExportForeachFuncItem>()
{ return "rs export foreach"; }
} // end namespace rsinfo
class RSInfo {
public:
typedef const uint8_t* DependencyHashTy;
typedef android::Vector<std::pair<const char*, const char*> > PragmaListTy;
typedef android::Vector<uint32_t> ObjectSlotListTy;
typedef android::Vector<const char *> ExportVarNameListTy;
typedef android::Vector<const char *> ExportFuncNameListTy;
typedef android::Vector<std::pair<const char *,
uint32_t> > ExportForeachFuncListTy;
public:
// Return the path of the RS info file corresponded to the given output
// executable file.
static android::String8 GetPath(const char *pFilename);
// Check whether this info contains the same source hash, compile command line, and fingerprint.
// If not, it's an indication we need to recompile.
bool IsConsistent(const char* pInputFilename, const DependencyHashTy& sourceHash,
const char* compileCommandLine, const char* buildFingerprint);
private:
rsinfo::Header mHeader;
char *mStringPool;
// Pointer to the hash of the souce file, somewhere in the string pool.
DependencyHashTy mSourceHash;
// Pointer to the command used to compile this source, somewhere in the string pool.
const char* mCompileCommandLine;
// Pointer to the build fingerprint of Android when the source was compiled, somewhere in the
// string pool.
const char* mBuildFingerprint;
PragmaListTy mPragmas;
ObjectSlotListTy mObjectSlots;
ExportVarNameListTy mExportVarNames;
ExportFuncNameListTy mExportFuncNames;
ExportForeachFuncListTy mExportForeachFuncs;
// Initialize an empty RSInfo with its size of string pool is pStringPoolSize.
RSInfo(size_t pStringPoolSize);
// layout() assigns value of offset in each ListHeader (i.e., it decides where
// data should go in the file.) It also updates fields other than offset to
// reflect the current RSInfo object states to mHeader.
bool layout(off_t initial_offset);
public:
~RSInfo();
// Implemented in RSInfoExtractor.cpp.
static RSInfo *ExtractFromSource(const Source &pSource,
const DependencyHashTy &sourceHashToEmbed,
const char* compileCommandLineToEmbed,
const char* buildFingerprintToEmbed);
// Implemented in RSInfoReader.cpp.
static RSInfo *ReadFromFile(InputFile &pInput);
// Implemneted in RSInfoWriter.cpp
bool write(OutputFile &pOutput);
void dump() const;
// const getter
inline bool isThreadable() const
{ return mHeader.isThreadable; }
inline bool hasDebugInformation() const
{ return mHeader.hasDebugInformation; }
inline const PragmaListTy &getPragmas() const
{ return mPragmas; }
inline const ObjectSlotListTy &getObjectSlots() const
{ return mObjectSlots; }
inline const ExportVarNameListTy &getExportVarNames() const
{ return mExportVarNames; }
inline const ExportFuncNameListTy &getExportFuncNames() const
{ return mExportFuncNames; }
inline const ExportForeachFuncListTy &getExportForeachFuncs() const
{ return mExportForeachFuncs; }
const char *getStringFromPool(rsinfo::StringIndexTy pStrIdx) const;
rsinfo::StringIndexTy getStringIdxInPool(const char *pStr) const;
// setter
inline void setThreadable(bool pThreadable = true)
{ mHeader.isThreadable = pThreadable; }
public:
enum FloatPrecision {
FP_Full,
FP_Relaxed,
};
// Return the minimal floating point precision required for the associated
// script.
FloatPrecision getFloatPrecisionRequirement() const;
};
// Returns the arguments concatenated into one string.
std::string getCommandLine(int argc, const char* const* argv);
} // end namespace bcc
#endif // BCC_RS_INFO_H